数据结构
⚡️数据结构-第一章
⚡️抽象数据类型案例
⚡️数据结构-第二章(1)-线性结构
⚡️数据结构-第二章(2)-线性表的顺序表示和实现
⚡️数据结构-第二章(3)-顺序表(含代码)
⚡️数据结构-第二章(4)-顺序表案例(含代码)
⚡️数据结构-第二章(5)-链式存储结构
⚡️数据结构-第二章(6)-单链表基本操作的实现
⚡️数据结构-第二章(7)-双向链表和循环链表
⚡️数据结构-第二章(8)-线性表的应用(线性表合并)
链栈的表示和实现
链栈是指采用链式结构实现的栈。通常链栈采用单链表来表示。
需要注意的是:链栈的指针方向与单链表是相反的。
链栈的节点结构和单链表的结构相同,在此 S t a c k N o d e StackNode StackNode表示,定义如下:
typedef struct StackNode
{
//构造一个空栈,栈顶指针置空
ElemType data;
struct StackNode* next;
}StackNode, *LinkStack;
由于栈的主要操作是在栈顶插入和删除,显然以链表的头部作为栈顶是最为方便的,而且没有必要像单链表那样为了操作方便附加一个头节点。
链栈的初始化
Status InitStack(LinkStack &S)
{
S=NULL;
return OK;
}
判断链栈是否为空
链栈的入栈
和顺序栈的入栈操作不同在于:链栈在入栈前不需要判断栈是否满,只需要为入栈元素动态分配一个节点空间。
【算法步骤】
- ① 为入栈元素 e 分配空间,用指针 p 指向。
- ② 将新节点数据域置为 e。
- ③将新节点插入栈顶。
- ④ 修改栈顶指针为 p。
Status Push(LinkStack &s, SElemType e)
{
//在栈顶插入元素e
p = new StackNode; //生成新节点
// p = (StackNode*)malloc(sizeof(StackNode));
p->data = s; //将新节点数据域置为e
p->next = s;//将新节点插入栈顶
s=p; //修改栈顶指针为p
return OK;
}
链栈的出栈
和顺序栈一样,链栈在出栈前也需要判断栈是否为空,不同之处在于:链栈的出栈后需要释放出栈元素的栈顶空间。
【算法步骤】
-
① 判断栈是否为空,若空则返回 E R R O R ERROR ERROR。
-
② 将栈顶元素赋给e。
-
③ 临时保存栈顶元素空间,以备释放。
-
④ 修改栈顶指针,指向新的栈顶元素。
-
⑤ 释放原栈顶元素的空间。
Status Pop(LinkStack &s, SElemType &e)
{
//删除s的栈顶元素,用e返回其值
if(NULL == s)
return ERROR; //栈空
e = s->data; //将栈顶元素赋给e
p = s; //用p临时保存栈顶元素空间,以备释放
s = s->next; //修改栈顶指针
delete p; //释放原栈顶元素的空间
return OK;
}
取栈顶元素
与顺序栈一样,当栈非空时,此操作返回当前栈顶元素的值,栈顶指针 s 保持不变。
SElemType GetTop(LinkStack s)
{
//返回s的詹元素,不修改指针
if(s) //栈非空
return s->data;//返回栈顶元素的值,栈顶指针不变
}
总结
期待大家和我交流,留言或者私信,一起学习,一起进步!