数据结构复习:堆栈

1、堆栈的抽象数据类型描述

堆栈(Stack):具有一定操作约束的线性表。只在一端(栈顶,Top)做插入、删除

  • 插入数据:入栈(push)
  • 删除数据:出栈(pop)
  • 后入先出:Last In First Out(LIFO)

数据对象集:一个有0个或多个元素的有穷线性表

操作集:长度为MaxSize的堆栈S属于Stack,堆栈元素item属于ElementType

  • Stack CreateStack(int MaxSize):生成空堆栈,其最大长度为Maxsize
  • int IsFull(Stack S,int MaxSize):判断堆栈S是否已满
  • void Push(Sstack S,ElementType item):将元素item压入堆栈
  • int IsEmpty(Stack S):判断堆栈S是否为空
  • ElementType Pop(Stack S):删除并返回栈顶元素

 如上图所示:先创建一个堆栈,然后pushA,B,C,D,然后一直pop出来的序列是DCBA

 

2、堆栈的顺序存储实现

栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成。

可用一个结构来表示堆栈:

#define MaxSize <存储数据元素的最大个数>
typedef struct SNode*Stack;
struct SNode{
        ElementType Data[MaxSize];   //数组,数组的分量是ElementType类型
        int Top;    //指示栈顶的位置,实际上是栈顶数据的下标是多少
};

(1)入栈

 

(2)出栈 

(3)【例】用一个数组实现两个堆栈,要求最大的利用数组空间,使数组只要有空间入栈操作就可以成功。

【分析】一种较好的方法是使两个栈分别从数组的两头开始向中间生长,当两个栈的栈顶指针相遇时,表示两个栈都满了。

定义其堆栈结构:

其push和pop操作:

 

3、堆栈的链式存储实现

栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。

栈顶指针Top应该在链表的哪一头呢?(一定是指向链表的头部)

 

 

 

定义其结构,包含两个域:data域和next域

typedef struct SNode *Stack;
struct SNode{
        ElementType Data;
        struct SNode *Next;
};
Stack CreateStack()    //生成堆栈的头结点
{ /* 构建一个堆栈的头结点,返回指针 */
    Stack S;
    S =(Stack)malloc(sizeof(struct SNode));
    S->Next = NULL;
    return S;
}

int IsEmpty(Stack S)
{                     
    /*判断堆栈S是否为空,若为空函数返回整数1,否则返回0 */
    return ( S->Next == NULL );
}
void Push( ElementType item, Stack S)
{ /* 将元素item压入堆栈S */
    struct SNode *TmpCell;
    TmpCell=(struct SNode *)malloc(sizeof(struct SNode));
    TmpCell->Element = item;
    TmpCell->Next = S->Next;
    S->Next = TmpCell;
}
ElementType Pop(Stack S)
{ /* 删除并返回堆栈S的栈顶元素 */
    struct SNode *FirstCell;
    ElementType TopElem;
    if( IsEmpty( S ) ) {
    printf(“堆栈空”); return NULL;
    } else {
        FirstCell = S->Next;
        S->Next = FirstCell->Next;
        TopElem = FirstCell ->Element;
        free(FirstCell);
        return TopElem;
    }
}

 

4、堆栈应用:表达式求值。中缀表达式转换为后缀表达式

中缀表达式求值:

基本策略:将中缀表达式转换为后缀表达式,然后求值。

观察一个简单的例子: 2+9/3-5     的后缀表达式为   2 9 3 / + 5 -

       1.运算数相对顺序不变

       2.运算符号顺序发生改变(需要存储等待中的运算符号用到堆栈。要将当前运算符与等待中最后一个运算符比较)

  • 上述例子意思是:
  • 来了一个a,输出;
  • 来了个 * 号,push进堆栈;
  • 左括号( ,push进堆栈 ; 
  • b,输出
  • +号,push进堆栈
  • c,输出
  • 右括号 ),pop出+号,左括号。堆栈里只剩下*号
  • / 号,抛出称号,push进除号

 

中缀表达式如何转换为后缀表达式

中缀转换为后缀实例: ( 2*(9+6/3-5)+4 )

 

 

 

参考:浙大公开课《数据结构》——陈越、何钦铭

 

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值