顺序栈 定义 进栈 出栈 共享栈 链栈 括号匹配 表达式求值 C语言实现

栈的顺序存储

栈(Stack)是只允许在一端进行插入和删除的线性表

n个不同元素进栈,出栈元素不同排列的个数[1/(n+1)]C2n,n

定义

#define MaxSize 10//栈中最大元素个数
typedef struct{
    ElemType data[MaxSize];//栈中元素
    int top;//栈顶指针
}SqStack;
  1. 栈顶指针:S.top,指向当前栈顶元素的位置
  2. 栈顶元素:S.data[S.top]
  3. 进栈:栈不满,栈顶指针加1,再送元素到栈顶元素
  4. 出栈:栈非空,先取栈顶元素,再将栈顶指针减1
  5. 栈空:S.top=-1
  6. 栈满:S.top==MaxSize-1
  7. 栈长:S.top+1

初始化

void InitStack(SqStack &S){
    S.top=-1;//初始化栈顶指针
}

进栈

bool Push(SqStack &S,ElemType x){
    if(S.top==MaxSize-1){
        return false;
    }
    S.data[++S.top]=x;//指针先加1,元素再入栈
    return true;
}

出栈

bool Pop(SqStack &s,ElemType &x){
    if(S.top==-1){
        return false;
    }
    x=S.data[S.top--];//元素先出,指针减1
    return true;
}

共享栈

两个栈的栈底分别设置在一个数组的两端,栈顶向中间延伸

#define MaxSize 10
typedef struct{
    ElemType data[MaxSize];
    int top[2];//0,1号栈顶指针
}ShStack;

//初始化栈
void InitStack(ShStack &S){
    S.top[0]=-1;
    S.top[1]=MaxSize;
}
  1. 栈空:top0=-1 0号栈空;top1=MaxSize 1号栈空
  2. 栈满:top1-top0=1
  3. 0号进栈,top0先加1再赋值
  4. 1号进栈,top1先减1在赋值

入栈

//i为栈号,i=0表示左边的栈,i=1表示右边的栈,x是入栈元素
int Push(ShStack &S,int i,ElemType x){
    if(i<0||i>1){
        printf("栈号输入不对");
        exit(0);
    }
    if(S.top[1]-S.top[0]==1){
        printf("栈满\n");
        return 0;
    }
    switch(i){
        case 0: S.data[++S.top[0]]=x;
            return 1;
            break;
        case 1: S.data[--S.top[1]]=x;
            return 1;
    }
}

出栈

//出栈,i=0表示左边的栈,i=1表示右边的栈
ElemType pop(ShStack &S,int i){
    if(i<0||i>1){
        printf("栈号输入错误\n");
        exit(0);
    }
    switch(i){
        case 0:
            if(S.top[0]==-1){
                printf("栈空\n");
                return -1;
            }
            else{
                return S.data[S.top[0]--];
            }
        case 1:
            if(S.top[1]==MaxSize){
                printf("栈空\n");
                return -1;
            }
            else{
                return S.data[S.top[1]++];
            }
    }
}

栈的链式存储

链栈(不存再栈满上溢,所有操作都是在链表表头进行的)

//定义
typedef struct LinkNode{
    ElemType data;//数据域
    struct LinkNode *next;//指针域
}*LiStack;
  1. 入栈就是单链表的头插法
  2. 出栈就是单链表删除头结点

栈的应用

括号匹配

在这里插入图片描述

bool bracketCheck(char str[],int length){
    SqStack S;
    InitStack(S);
    for(int i=0;i<length;i++){
        if(str[i]=='(' || str[i]=='[' || str[i]=='{'){
            Push(S,str[i]);//扫描左括号,入栈
        }else{
            if(StackEmpty(S)){
                return false;
            }
            char topElem;
            Pop(S,topElem);//栈顶元素出栈
            if(str[i]==')' && topElem!='(')
                return false;
            if(str[i]==']' && topElem!='[')
                return false;
            if(str[i]=='}' && topElem!='{')
                return false;
        }
    }
    return StackEmpty(S);
}

表达式求值

在这里插入图片描述

递归

递归调用:将原始问题转换为属性相同,规模较小的问题

函数调用,系统为每一层的返回点,局部变量,传入实参等开辟了递归工作栈来进行数据存储(递归次数过多容易栈溢出)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值