【数据结构】堆栈

什么是堆栈

  1. 计算机如何表达式求值
    eg: (5+6/2-3*4)
    分析:由运算数和运算符号构成;不同运算符号优先级不一样

后缀表达式:运算符号位于两个运算数之后
求值策略:从左往右“扫描”,逐个处理运算数和运算符号
启示:顺序存储运算数,并在需要时倒序输出

堆栈的ADT

  1. 定义:具有一定操作约束的线性表
    只在一端(栈顶)做插入、删除

    插入数据:入栈(Push)
    删除元素:出栈 (Pop)
    后入先出:Last In First Out (LIFO)

  2. ADT描述

类型名称:堆栈(Stack)
数据对象集:一个有0个或多个元素的有穷线性表
操作集:长度为Maxsize的堆栈$S in Stack$,堆栈元素$item in ElementType$
(1)Stack CreatStack(MaxSize):生成空堆栈,其最大长度为Maxsize
(2)int IsFull(Stack S,int MaxSize):判断堆栈S是否已满
(3)void Push(Stack S, ElementType item):将元素item压入堆栈
(4)int IsEmpty(Stack S):判断堆栈S是否为空
(5)ElementType Pop(Stack S):删除并返回栈顶元素

堆栈的顺序存储实现

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

#define MaxSize <个数>
typedef struct SNode *Stack;
struct SNode{
    ElementType Data[MaxSize];
    int top;
}

(1)入栈

void Push(ElementType item, Stack PtrS){
    if(PtrS->Top==MaxSize-1){        //用数组实现的,所以一定得注意大小
        cout<<"栈满";
        return;
    }else{
    PtrS->Data[++(PtrS->Top)]=item;
    return;
   }
}

(2)出栈

ElementType Pop(Stack PtrS){
    if(PtrS->Top==-1){            //注意该特殊情况
        cout<<"空栈";
        return ERROR;
    }
    return Ptr->Data[(PtrS->Top)--];
}

思考题:一个数组实现两个堆栈,最大利用数组空间

#define MaxSize <大小>
typedef struct DNode *DStack;
struct DNode{
    ElementType Data[MaxSize];
    Stack Top1;
    Stack Top2;
}S
S.Top1=-1;
S.Top2=MaxSize;

(1) Push

void Push(DStack PtrS,ElementType item, int Tag){
    if(PtrS->Top2-PtrS->Top1==1){
        cout<<"栈满";
        return;
    }
    if(Tag==1)
        PtrS->Data[++(PtrS->Top1)] = item;
    else
        PtrS->Data[--(PtrS->Top2)] = item;
}

(2)Pop

ElementType Pop(Dstack PtrS,int Tag){
    if(Tag==1){
        if(PtrS->Top1==-1){
        cout<<“栈空”;
        return;}
        else return PtrS->Data[(PtrS->Top1)--];
    }else{
        if(PtrS->Top2==MaxSize-1){
        cout<<“栈空”;
        return;}    
        else return PtrS->Data[(PtrS->Top2)++];
    }
}

堆栈的链式存储实现

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

typedef struct SNode *Stack;
struct SNode{
    ElementType Data;
    Stack Next;
}

(1)堆栈的初始化
选择链表的链头作为堆栈的top。一般为堆栈构建一个头节点

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

(2)判断堆栈S是否为空

int IsEmpty(Stack PtrS){
    return (PtrS->Next==NULL);
}

(3)入栈

void Push(ElementType item, Stack S){
    Stack TmpCell;
    TmpCell=(Stack)malloc(sizeof(struct SNode));
    TmpCell->Data=item;
    TmpCell->Next=S->Next;
    S->Next=TmpCell;
}

(4)出栈

ElementType Pop(Stack S){
    Stack FirstCell;
    ElementType TopElem;
    if(IsEmpty(S)){
        cout<<"堆栈空";
        return NULL;
    }else{
         FirstCell=S->Next;
        S->Next=FirstCell->Next;
        TopElem=FirstCell->Element;
        free(FirstCell);
        return TopElem;
    }
}

堆栈应用:表达式求值

基本策略:把中缀表达式转化为后缀表达式

其他应用:
(1)函数调用及递归实现
(2)深度优先搜索
(3)回溯算法

原文地址:https://www.cnblogs.com/maxwell-maxwill/p/12310282.html