目录
前言
一、栈的链式储存结构
二、栈的链式储存结构的操作
2.1 进栈操作
2.2 出栈操作
总结
前言
讲完了栈的顺序储存结构,我们现在来看看栈的链式存储结构,简称为链栈。
由于单链表中有头指针,而栈顶指针也是必不可少的。所以,我们将它们合二为一,即对于栈链来说是不需要头结点的。
需要注意的一点是,相比与栈的顺序储存结构,对于栈链来说,基本不存在栈满的情况。那是因为链式储存结构的特点就在于内存中的任何有空位的地方可以进行储存,除非内存已经没有可使用的空间了,那时计算机系统也将面临死机崩溃的情况了。
一、栈的链式储存结构
链栈的代码实现如下:
typedef struct stacknode{int data; //暂定数据类型为int型 struct stacknode *next;}stacknode,*linkstackptr;typedef struct{linkstackptr top;//栈顶的结点 int count; //结点的数量 }linkstack;
但对于空栈来说,链表的原定义是头指针指向空,那么链栈的空其实就是top=NULL的时候。
二、栈的链式储存结构的操作
2.1 进栈操作
假设元素值为e的新结点是s,top为栈顶指针,代码如下:
status push(linkstack *a,int e){linkstackptr s=(linkstackptr)malloc(sizeof(stacknode)); //建立新结点 s.data=e; s.next=a.top; //把当前的栈顶元素赋值给新结点的直接后继 a.top=s; //把新的结点赋值给栈顶指针 a.count++; //栈内元素数量+1 return ok;}
2.2 出栈操作
出栈操作同样是很简单的三步操作。假设变量p用来储存要删除的栈顶结点,将栈顶指针下移一位,最后释放p即可,实现代码如下:
status pop(linkstack *a,int *e){linkstackptr p;*e=a.top.data;p=a.top; //将栈顶结点赋值给p a.top=a.top.next; //使得栈顶结点下移一位,指向后一结点 free(p); //释放结点p a.count--;return ok;}
总结
链栈的进栈和出栈的操作都很简单,没有任何的循环操作,时间复杂度均为O(1)。
对比一下顺序栈与链栈,它们在时间复杂度上是一样的,均为O(1)。所以,如果栈的使用过程中元素的变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。