当前位置:   article > 正文

【数据结构】栈(详解)_数据结构栈讲解

数据结构栈讲解

目录

1 顺序栈的定义

2 顺序栈的基本操作

2.1 初始化:

2.2 判空栈

2.3 进栈

2.4 出栈

2.5 读栈顶元素

3 共享栈

3.1 共享栈的实现

3.2 基本操作

3.2.1 栈1进栈:

3.2.2 栈2进栈:

4 栈的链式存储

4.1 链栈的定义

4.2 链栈的基本操作

4.2.1 进栈

4.2.2 出栈

4.3 链栈的优点


1 顺序栈的定义

  • 数据结构中的栈(Stack)是一种特殊的线性表,其特殊性在于它只能在一端进行插入和删除操作,这一端被称为栈顶,另一端则被称为栈底。栈遵循“后进先出”(Last In First Out,LIFO)的原则,即最后一个被放入栈中的元素总是第一个被取出。
  • 在编程中,栈常用于实现函数调用、表达式求值、数制转换、迷宫求解等算法。例如,在函数调用中,每调用一个函数,就将该函数的局部变量和返回地址压入调用栈中,当函数返回时,再从调用栈中弹出相应的数据。这种机制确保了函数调用的正确性和顺序性。

名词解释:

  • 栈顶:允许插入删除的一端。
  • 栈底:不允许插入删除的一端。
  • 空栈:不包含任何元素的空表。

  1. #define MaxSize 50
  2. typedef struct{
  3. ElemType data[MaxSize];
  4. int top;
  5. }Stack;

2 顺序栈的基本操作

2.1 初始化

  1. void InitStack(Stack &S){
  2. S.top=-1;
  3. }

2.2 判空栈

  1. #define true 1
  2. #define false 0
  3. bool EmptyStack(Stack S){
  4. if(S.top==-1) return true;
  5. else return false;
  6. }

2.3 进栈

首先,判断是否栈满。如栈满,则退出程序。若未满,则先让top指针加一,在进行入栈操作。

  1. bool Push(Stack &S,ElemType e){
  2. if(S.top==MaxSize-1) return false; //栈满?
  3. S.data[++S.top]=e;
  4. return true;
  5. }

2.4 出栈

首先,判断是否栈空。若空,则退出程序。反之,则让e等于出栈元素,再让top指针减1。

  1. bool Pop(Stack &S,ElemType &e){
  2. if(S.top==-1) return false; #判栈空
  3. e=S.data[S.top--];
  4. return true;
  5. }

2.5 读栈顶元素

  1. bool GetTop(Stack S,ElemType &e){
  2. if(S.top==-1) return false; //判栈空
  3. e=S.data[S.top];
  4. return true;
  5. }

读栈顶元素与出栈类似,只是读并没有将元素出栈。

注意:

在本节定义中,栈的初始化是将S.top初始为-1。但是,S.top也可以初始为0。

当初始化S.top==0时,

进栈操作的代码:S.data[++S.top]=e;

应改为:S.data[S.top++]=e;

出栈操作的代码:e=S.data[S.top--];

应该为:e=S.data[--S.top];

3 共享栈

3.1 共享栈的实现

  1. #define MaxSize 50
  2. typedef struct{
  3. ElemType data[MaxSize];
  4. int top1=0;
  5. int top2=MaxSize-1;
  6. }ShareStack;

3.2 基本操作

这里只拿进栈操作来实现,其余的可以自行动手练习。

3.2.1 栈1进栈:

  1. bool Pop(ShareStack &S,ElemType e){
  2. if((S.top1+1)==S.top2) return false; #栈满?
  3. S.data[S.top1++]=e;
  4. return true;
  5. }

3.2.2 栈2进栈:

  1. bool Pop(ShareStack &S,ElemType e){
  2. if((S.top1+1)==S.top2) return false; #栈满?
  3. S.data[S.top2--]=e;
  4. return true;
  5. }

4 栈的链式存储

4.1 链栈的定义

栈的链式存储称为链栈,采用单链表的头插法(不包含头结点),head指向栈顶结点。

  1. typedef struct LNode{
  2. ElemType *data;
  3. struct LNode *next;
  4. }LNode,*LStack;

4.2 链栈的基本操作

4.2.1 进栈

  1. bool Pop(LStack &S,ElemType e){
  2. LNode *p=(LNode*)malloc(sizeof(LNode));
  3. if(S==NULL){
  4. S=p;
  5. p->next=NULL
  6. }
  7. else{
  8. p->next=S->next;
  9. S->next=p;
  10. }
  11. return true;
  12. }

4.2.2 出栈

  1. bool Push(LStack &S,ElemType &e){
  2. if(S==NULL) return false;
  3. if(S->next==NULL){
  4. e=S->data;
  5. S->next=NULL;
  6. }
  7. else{
  8. e=S->data;
  9. S->next=S->next->next;
  10. }
  11. return true;
  12. }

4.3 链栈的优点

  • 不链栈不存在满栈上溢的情况;
  • 链栈便于结点的插入与删除;
  • 入栈和出栈的操作都在表头。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/905918
推荐阅读
相关标签
  

闽ICP备14008679号