版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z498596750/article/details/79361056
栈是一个特殊的线性表,后进先出,既然是线性表,就会分为顺序存储和链式存储,下面就是栈的链式存储部分,也称作链栈。单链表是有头指针头节点的,通常链栈的栈顶就相当于头指针,因为初始化的链栈是空的,即top=NULL,因为栈顶的存在,单链表的头节点就没什么意义了,也就不需要了。对于链栈来说,几乎不存在栈满的情况,除非电脑内存满了。链栈的操作和单链表的操作非常相似,只是插入、删除、获取区别较大,实现代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef int LSEletype;//定义链栈存储的数据类型
typedef struct StackNode{//定义链栈存储的结构体(节点)
LSEletype data;
struct StackNode *next;
}StackNode;
typedef StackNode *StackLinkP;//定义指针类型的栈顶(相当于链表的头指针)
typedef struct StackLink{//定义链栈的属性
StackLinkP top;
int count;
}StackLink;
StackLink init(){
StackLink sl;
sl.top=NULL;
sl.count=0;
return sl;
}
int stackEmpty(StackLink s){
int result;
if(s.count==0){
result=0;
}else{
result=1;
}
return result;
}
void push(StackLink *s,LSEletype e){
//定义一个指向节点的指针(相当于链表头指针)
StackLinkP p;
//通过指针创建节点并赋值
p=(StackLinkP)malloc(sizeof(StackNode));
p->data=e;
p->next=s->top;//把栈顶的指向给他再让栈顶指向他
s->top=p;
s->count++;//链栈长度自增
}
void pop(StackLink *s,LSEletype *e){
int r=stackEmpty(*s);//判断该栈是否为空
if(r==1){
StackLinkP p=s->top;//拿到要删除的节点
(*e)=p->data;
s->top=p->next;//让栈顶指向下一个节点
free(p);
s->count--;
}else{
return ;
}
}
void getEle(StackLink s,LSEletype *e){
StackLinkP p=s.top;
*e=p->data;
}
int main()
{
StackLink s=init();
LSEletype g;
LSEletype e=666,f=888;
printf("链栈是否为空:\n%d\n",stackEmpty(s));
push(&s,e);
push(&s,f);
printf("链栈是否为空:\n%d\n",stackEmpty(s));
getEle(s,&g);
printf("当前栈顶数据为:\n%d\n",g);
pop(&s,&g);
getEle(s,&g);
printf("删除一个数据后,当前栈顶数据为:\n%d\n",g);
pop(&s,&g);
printf("链栈是否为空:\n%d\n",stackEmpty(s));
return 0;
}