栈的链式存储结构
栈的链式存储结构与线性表的链式存储结构相同,是通过由结点构成的单链表实现的。为操作方便我们使用无头结点的单链表。此时栈顶为单链表的第一个结点,整个单链表为一个链栈。
- 1. 链栈的类型定义:
//链栈的类型定义 typedef struct node { datatype data; /*数据域*/ struct node * next; /*指针域*/ }LinkStack; /*链栈结点类型*/ |
top 为栈顶,它唯一地确定一个栈。空栈时为NULL。因为链栈地动态分配空间的,所以操作时无需考考虑上益问题。
下面是链栈的部分的基本操作:
1.判断空栈
//判别空栈 int StackEmpty(LinkStack *top) { return (top?0:1); } |
返回0,则不为空。
2.取栈顶元素
//取栈顶元素 datatype GetTop(LinkStack *top) { if(!top) { printf("/n链表是空的!"); return 0; } return top->data; } |
3.入栈
//入栈 LinkStack *Push(LinkStack *top,datatype x) { LinkStack *p; p=(LinkStack *)malloc(sizeof(LinkStack));//分配空间 p->data=x; /*设置新结点的值*/ p->next=top; /*将新元素插入栈中*/ top=p; /*将新元素设为栈顶*/ return top; } |
4.出栈
//出栈 LinkStack *Pop(LinkStack *top) { LinkStack *p; if(!top) { printf("/n链栈是空的!"); return NULL; } //判断是否为空栈n p=top; //指向被删除的栈顶 top=top->next; //修改栈顶指针 free(p); return top; } |
5.Main函数测试
main() { int a[5]={1,2,3,4,5},i,isEmtpy; LinkStack *linkStack; linkStack = (LinkStack *)malloc(sizeof(LinkStack)); linkStack->data=1; linkStack->next=NULL; for(i=1;i<5;i++) { linkStack=Push(linkStack,a[i]); } //取栈顶元素为 printf("栈顶元素为:"); printf("%d/n",GetTop(linkStack)); //把栈顶元素出栈 linkStack=Pop(linkStack); //出栈后的栈顶元素是 printf("出栈后的栈顶元素是:"); printf("%d",GetTop(linkStack)); printf("/n");
//判断是否为空栈 isEmtpy = StackEmpty(linkStack); if(isEmtpy==0) printf("linkStack为非空链栈!/n"); else printf("linkStack为空链栈!/n"); } |
说明:
- 1) 链栈不必设头结点,。因为链式栈都是对头结点进行操作,如果设置了头结点 ,会更麻烦。
- 2) 链栈一般不会出现栈满情况,除非空间不足,导致malloc分配失败。
- 3) 链栈的入栈,出栈操作就是栈顶的插入和删除操作,修改指针即可。
- 4) 采用链栈的优点是:可使用多个栈共享空间,当栈中元素个数变化较大时,且存在多个栈的情况下,链栈是栈的首选存储方式。