【数据结构】栈(详解)

目录

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)的原则,即最后一个被放入栈中的元素总是第一个被取出。
  • 在编程中,栈常用于实现函数调用、表达式求值、数制转换、迷宫求解等算法。例如,在函数调用中,每调用一个函数,就将该函数的局部变量和返回地址压入调用栈中,当函数返回时,再从调用栈中弹出相应的数据。这种机制确保了函数调用的正确性和顺序性。

名词解释:

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

#define MaxSize 50
typedef struct{
    ElemType data[MaxSize];
    int top;
}Stack;

2 顺序栈的基本操作

2.1 初始化:

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

2.2 判空栈

#define true 1
#define false 0

bool EmptyStack(Stack S){
    if(S.top==-1) return true;
    else return false;
}

2.3 进栈

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

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

2.4 出栈

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

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

2.5 读栈顶元素

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

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

注意:

在本节定义中,栈的初始化是将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 共享栈的实现

#define MaxSize 50

typedef struct{
    ElemType data[MaxSize];
    int top1=0;
    int top2=MaxSize-1;
}ShareStack;

3.2 基本操作

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

3.2.1 栈1进栈:

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

3.2.2 栈2进栈:

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

4 栈的链式存储

4.1 链栈的定义

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

typedef struct LNode{
    ElemType *data;
    struct LNode *next;
}LNode,*LStack;

4.2 链栈的基本操作

4.2.1 进栈

bool Pop(LStack &S,ElemType e){
    LNode *p=(LNode*)malloc(sizeof(LNode));
    if(S==NULL){
        S=p;
        p->next=NULL
    }
    else{
        p->next=S->next;
        S->next=p;
    }
    return true;
}

4.2.2 出栈

bool Push(LStack &S,ElemType &e){
    if(S==NULL) return false;
    if(S->next==NULL){
        e=S->data;
        S->next=NULL;
    }
    else{
        e=S->data;
        S->next=S->next->next;
    }
    return true;
}

4.3 链栈的优点

  • 不链栈不存在满栈上溢的情况;
  • 链栈便于结点的插入与删除;
  • 入栈和出栈的操作都在表头。
  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值