#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
//定义节点的结构体
typedef struct Node{
int data; //节点存放的数据
struct Node * pNext; //节点的指针,指向下一个Node
}NODE,* PNODE;
//定义栈的结构体,栈只需要两个属性,一个是顶端top,另一个是底端bottom
typedef struct Stack{
PNODE pTop;
PNODE pBottom;
}STACK,* PSTACK;
void init(PSTACK);
void push(PSTACK,int);
void traverse(PSTACK);
bool pop(PSTACK,int *);
bool is_empty(PSTACK);
void clear(PSTACK);
//伪算法的实现思路
/*
1.首先通过init()函数构造一个空的栈,这个空的栈的顶部和底部同时指向一个空的头指针,这样就生成了一个空的栈
2.push()函数把对应的值放到栈上,ptop原本指向底部,此时需要指向新加入的节点,同时新加入的节点指向头结点,这样就生成了1个元素的栈,其他类似
*/
//初始化 构造一个空栈
void init(PSTACK pstack){
pstack->pTop=(PNODE)malloc(sizeof(NODE)); //生成一个新的节点
if(pstack->pTop==NULL){
printf("动态内存分配失败!\n");
exit(-1);
}
pstack->pBottom=pstack->pTop; //让ptop和pbottom指向同一个空间(节点)
pstack->pBottom->pNext=NULL; //将头结点的指针域清空
}
//压栈
void push(PSTACK pstack,int val){
PNODE pNew=(PNODE)malloc(sizeof(NODE)); //创建一个新节点
pNew->data=val; //将值赋值给新节点的data
pNew->pNext=pstack->pTop; //将新节点的指针指向栈顶,每次新加入的元素都是栈顶,它首先需要指向以前的栈顶
pstack->pTop=pNew; //栈顶变为新节点的值
}
//出栈
//定义一个临时变量,保存ptop的值,然后将ptop指向下一个元素,然后释放临时变量;必须要释放内存,所以先保存之前的地址,然后再释放掉;
//将出栈的元素保存到val形参所指向的变量中
bool pop(PSTACK pstack, int * val){
if(is_empty(pstack)){
printf("出栈失败,栈为空\n");
return false;
}else{
PNODE r=pstack->pTop;
*val=r->data;
pstack->pTop=r->pNext;
free(r);
r=NULL;
}
}
/*
free做的是释放指针指向的用malloc申请的特定的内存空间,而不是指针本身。
结论:使用方法 对于用malloc分配空间的指针p, 使用过后要这样释放:
free(p); //此处只是释放掉了内存,p变量里面的值还是指向原来的地址,
//因为地址对应的内存已经被释放了,所以p指向的内存已经无法使用,因此应该将p的值置空;
p=NULL;
*/
//判断栈是否为空
bool is_empty(PSTACK pstack){
if(pstack->pTop==pstack->pBottom){
return true;
} else{
return false;
}
}
//遍历栈里面的元素
//思路 定义一个临时变量,临时变量的值为ptop的值,当临时变量的值不等于pbottom时,就不挺的循环,直到p=pbottom;
void traverse(PSTACK pstack) {
PNODE p=pstack->pTop;
while(p!=pstack->pBottom){
printf("%d ",p->data);//输出值
p=p->pNext; //p的指针下移
}
printf("\n");
return;
}
//清空栈里面的元素
void clear(PSTACK pstack){
if(is_empty(pstack)){
return;
} else{
PNODE p=pstack->pTop;
PNODE q=NULL;
while(p!=pstack->pBottom){
q=p->pNext; //用q保存p指向的元素的地址
free(p); //将p的空间释放
p=q; //p指向下一个元素,这样每次q都指向的是p的下一个元素;
}
pstack->pTop=pstack->pBottom; //最后要将pTop的值和pbottom的值一样;
}
}
int main(void){
STACK s;
init(&s);
push(&s,1);
push(&s,2);
push(&s,3);
push(&s,4);
push(&s,5);
push(&s,6);
traverse(&s);
clear(&s);
int val;
if(pop(&s,&val)){
printf("出栈成功,出栈的元素是%d\n",val);
}else{
printf("出栈失败!\n");
}
traverse(&s);
return 0;
}
/*
结果:
6 5 4 3 2 1
出栈失败,栈为空
出栈失败!
*/