【数据结构】五、栈

目录

一、栈的基本知识

1.栈(stack)是一个特殊的线性表

2.插入元素到栈顶(表尾)的操作称为入栈PUSH;从栈顶(表尾)删除最后一个元素的操作称为出栈POP

3.栈的应用案例:进制转换、括号匹配、表达式求值

4.进制转换案例

5.括号匹配案例

6.表达式求值案例

二、顺序栈

三、顺序栈的基本操作

1.顺序栈的定义

2.初始化

3.判断栈是否为空

4.求顺序栈的长度

5.清空顺序栈

6.销毁顺序栈

7.顺序栈的入栈

8.顺序栈的出栈

四、链栈

五、链栈的基本操作

1.链栈的定义

2.链栈的初始化

3.判断是否为空栈

4. 链栈的入栈

5.链栈的出栈

六、栈与递归 


一、栈的基本知识

1.栈(stack)是一个特殊的线性表,是将插入和删除操作限定在表尾的线性表。表尾成为栈顶Top,表头成为栈底Base。栈的特点:先进后出;栈也可以是顺序存储结构(顺序栈)或链式存储结构(链式栈)。

2.插入元素到栈顶(表尾)的操作称为入栈PUSH;从栈顶(表尾)删除最后一个元素的操作称为出栈POP。

3.栈的应用案例:进制转换、括号匹配、表达式求值

4.进制转换案例

5.括号匹配案例

先入栈的括号后匹配,后入栈的括号先匹配。

左括号入栈,遇到右括号就和栈顶的括号匹配,如果能匹配上就将栈顶元素出栈。然后继续匹配右括号和栈顶的元素。

6.表达式求值案例

这里运用的是运算符优先算法:

(1) 我们可以将表达式分为三部分:

表达式起始和结束符是假设的

(2) 需要用到两个栈

(3) 遍历表达式的字符

二、顺序栈

可以将顺序栈看为数组

对于顺序栈:栈底的元素从下标0开始

top指针指向栈顶元素 + 1的位置,base指针指向栈底元素

栈中元素个数 = top - base

三、顺序栈的基本操作

1.顺序栈的定义

typedef struct
{
    int *top;  //栈顶指针
    int *base;  //栈底指针
    int stackSize;  //栈的最大元素个数
}SqStack;

2.初始化

void initStack(SqStack &S)
{
    S.base = new int[MAXSIZE];
    S.top = S.base;
    S.stackSize = MAXSIZE;
}

3.判断栈是否为空

bool stackEmpty(SqStack S)
{
    if(S.top == S.base)
    {
        return true;
    }
    else
    {
        return false;
    }

4.求顺序栈的长度

int stackLength(SqStack S)
{
    return S.top - S.base;
}

5.清空顺序栈

并不需要一个一个得清除元素,只需当做一个空栈。

void clearStack(SqStack &S)
{
    //如果这个栈存在
    if(S.base)
    {
        S.top = S.base;
    }
}

6.销毁顺序栈

void destroyStack(SqStack &S)
{
    //如果这个栈存在
    if(S.base)
    {
        delete S.base;  //相当于将栈所占用的空间给释放
        S.stackSize = 0;
        S.top = S.base = NULL;
    }
}

7.顺序栈的入栈

void pushStack(SqStack &S, int e)
{
    //先判断栈是否已经满了
    if(S.top - S.base == S.stackSize)
    {
        return;
    }
    else
    {
        *S.top = e;  //top是指针,它指向的就是栈的元素
        S.top++;
        //也可以写为*S.top++ = e;
    }

8.顺序栈的出栈

int popStack(SqStack &S, int e)
{
    //先判断栈是否为空
    if(S.top == S.base)
    {
        return;
    }
    //要先--,因为top是指向栈顶元素的上一个地方
    S.top--;
    e = *S.top;
    //也可以写为e = *--S.top;
    return e;

四、链栈

链栈可以看作是单链表,有数据域和指针域

第n个结点的指针域指向的是第n-1个结点,且没有头结点,和单链表有区别

S头指针就是栈顶,头指针为NULL时表示空栈

五、链栈的基本操作

1.链栈的定义

typedef struct stackNode
{
    int data;
    struct stackNode *next;
}stackNode;  //将stackNode定义为struct stackNode类型
typedef struct stackNode *stackLink;  //将stackLink定义为struct stackNode*类型
//链栈表示stackLink S,结点表示stackNode *p;

2.链栈的初始化

void initStack(stackLink &S)
{
    S = NULL;
}

3.判断是否为空栈

bool isEmpty(stackLink &S)
{
    if(S == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
}

4. 链栈的入栈

void pushStack(stackLink &S, int e)
{
    stackNode *p = new stackNode;
    p->data = e;
    p->next = S;
    S = p;
}

5.链栈的出栈

返回出栈的元素

int popStack(stackLink &S, int e)
{
    e = S->data;
    stackNode *p = new stackNode;
    p = S;
    S = S->next;
    delete p;
    return e;
}

六、栈与递归 

函数的递归调用遵循后调用的先返回(返回就是函数执行完毕返回返回值),类似于栈的后进先出。而每次调用时需要用到的参数或变量都存在系统的栈里。所以递归需要系统提供栈来实现。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值