#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
//模拟栈的功能
//自定义数据类型
typedef struct Node//节点类型
{
int data;//存放的数据
struct Node *pNext;//下一个结点的地址
} NODE,*PNODE;//将数据类型起别名
typedef struct Stack//栈类型
{
PNODE pTop;//栈顶指针
PNODE pBottom;//栈底指针
}STACK,*PSTACK;
//初始化栈
void init(PSTACK ps)
{
/*
思想:让栈底和栈顶指针同时指向头结点
*/
ps->pBottom = (PNODE)malloc(sizeof(NODE));//创建头结点并赋值给栈底指针
if(NULL==ps->pBottom)
{
printf("动态内容分配失败");
exit(-1);//内存分配失败直接退出
}else{
ps->pTop = ps->pBottom;
ps->pBottom->pNext=NULL;
}
}
//压栈
void push(PSTACK ps,int value)
{
//思想:我们直接将栈顶指针指向新结点即可
PNODE p =(PNODE)malloc(sizeof(NODE));//创建结点
if(NULL == p)
{
printf("动态内容分配失败");
exit(-1);//内存分配失败直接退出程序
} else{
p->data=value;//给新结点赋值
p->pNext =ps->pTop;//新结点的指针指向前一个结点
ps->pTop = p;//栈顶指针指向新结点
}
}
//判断栈是否为空
int empty(PSTACK ps)
{
if(ps->pBottom == ps->pTop)
{
return 1;
} else{
return 0;
}
}
//出栈
int pop(PSTACK ps,int *value)
//将栈顶结点删除,并将删除结点的值返回
{
if(empty(ps))//当栈为空
{
printf("栈为空");
return 0;
}else{//栈非空进行出栈操作
PNODE r = ps->pTop;
ps->pTop = r->pNext;//将栈顶下移
free(r);//将出栈的结点内存释放掉
r=NULL;
return 1;
}
}
void show(PSTACK ps)//展示输出栈的内容
{
PNODE p = ps->pTop;
while(p!=ps->pBottom)
{
printf("%d ",p->data);
p=p->pNext;
}
}
//清空栈(恢复到空栈的情形)
void clear(PSTACK ps)
{
//思路:1.将栈中所有的结点的内存都释放掉
// 2.将栈顶指针指向头结点
/*
按照道理说:我们需要定义q p两个遍历指针才行
因为我们free(p)后,p所指向的结点都不存在了,那么里面的pNext都不存在了,但是好像还是可以
应该是不熟悉free方法的底层原理
*/
if(empty(ps))
{
return;//为空则直接截至
}else{
PNODE p = ps->pTop;//定义一个遍历指针
PNODE q = NULL;//定义遍历指针q
while(p!=ps->pBottom)
{ q=p->pNext;
free(p);
p=q;
}
ps->pTop = ps->pBottom;//栈顶和栈底都指向头结点
}
}
int main()
{
STACK s;//定义一个栈
init(&s);//初始化栈
push(&s,8);
push(&s,9);
clear(&s);
show(&s);
return 0;
}