赞
踩
栈的链式存储结构就是使用链表存储栈中数据元素,此时的栈称为链栈。通常采用带头结点的单链表存储栈。栈的操作权限在栈顶进行,可将头节点指针指向栈顶节点,如用top指针指向头结点,称为top结点。
a(n-1) |
a1 |
a0 |
图1.1 栈的逻辑结构
图1.2 栈的链式存储结构
- struct node
- {
- DataType data; //链式结点数据域类型及名称;
- struct node *next; //指针域类型及名称,指向次顶结点
- }
- tpedef struct node StackNode;
- StackNode *top;
top结点的指针指向栈顶元素,栈顶元素用top->next来引用,当top->next==NULL时表示为空。栈不为空时,top->next->data表示栈顶元素的值。链栈不会出现栈满的情况,只要有可用空间就可以申请元素来放新元素。故不需要事先估计栈的最大容量。
初始化如图,及建立一个空的链栈,只有top结点,其指针域为空。top结点需要申请才可以得到,代码如下:
- StackNode * InitStack()
- {
- NODE * top;
- top=(StackNode *)malloc(sizeof(StackNode)); //为top结点申请空间
- top->next=NUL; //top的指针域为空
- return(top)
- }
已知一个数据元素x以及链栈top,要求完成x进栈要求,如图所示
- StackNode * Push(StackNode * top,DataType x)
- {
- StackNode *p;
- p=(StackNode *)malloc (sizeof(StackNode)); //申请新结点p
- p->data=x; //x存储到p结点中
- p->next=top->next; //p指向栈顶结点
- top->next=p; //top结点指向p,p成为新的栈顶元素
- return(p);
- }
分析:假设栈中数据元素类型为整形,虚线代表p进栈后的指针指向。top的指针域指向栈顶元素,每个结点存放一个数据元素。x进栈需要先为x申请一个结点空间p并赋值为x,再将p插入到top结点之后,类似单链表中的插入结点到表头。x所在节点p插入到top结点之后,成为了新的栈顶结点。
出栈及删除栈顶结点。只要栈是非空的,删除top结点所指向的元素,操作类似于单链表中删除指定节点的后继。操作思路如图
- StackNode *Pop(StackNode *top){
- StackNode *p;
- if(top->next==NULL){ //判断栈是否为空
- printf("栈为空,无法出栈");
- return(top)}
- else{
- p=top->next; //p指向栈顶,待删除
- top->next=p->next; //top结点指针域跳过p,指向p的后继
- free(p); //释放p占用的空间
- return(top);
- }
算法中先判断栈是否为空,空栈无法出栈,在栈不空的情况下,删除top指针域所指向的结点并释放空间,即栈顶节点。
链栈的操作实际上还是单链表的操作,只是在操作中需要注意栈的操作要点即可。链栈解决了顺序栈的不足之处(“上溢”)。在实际中,通常是根据情况考虑选用顺序栈还是链栈。例如:当栈中元素最大个数可确定,且变化不大时,可选用顺序栈;当栈中元素个数不可估计,或者长度变化较大时,可选用链栈。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。