数据结构-------栈

定义:只允许在一端进行插入或删除操作的线性表。
栈顶:线性表允许进行插入删除的那一端。
栈底:固定的,不允许进行插入删除的另一端。
空栈:不含任何元素的空表。
特性:后进先出。(LIFO)
数学性质:n个不同的元素进栈,出栈元素不同排列的个数为(n+1)<sup>-1</sup>C<sup>n</sup><sub>2n</sub>
顺序栈
栈顶指针:S.data[S.top]
进栈:栈不满时,栈顶指针先加1,再送值到栈顶元素。
出栈:栈非空时,先取栈顶元素,再将栈顶指针减1.
栈空:S.top==-1  栈满:S.top==MAXSize-1  栈长:S.top+1
共享栈
定义:利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈底向共享空间的中间延申。
两个栈的栈顶指针都指向栈顶元素,top0=-1时,0号栈为空,top1=MAXSize时1号栈为空。仅当两个栈顶指针相邻(top1-top0=1)时,栈满。
0号栈进栈时,top0先加1再赋值,1号栈进栈时top1先减1再赋值;出栈则相反。
特点:为了更有效的利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才发生上溢。
链栈
优点:便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。便于结点的插入和删除。
应用
  • 括号匹配:遇到左括号进栈,遇到右括号出栈。算法结束,栈为空,否则括号序列不匹配。

  • 中缀表达式转后缀表达式:中缀表达式不仅依赖运算符的优先级,还有处理括号。后缀表达式已经考虑了运算符的优先级,没有括号,只有操作数和运算符。

中缀表达式转后缀表达式步骤:
1 根据操作符<op>的优先级来进行栈的变化
2 从左向右扫描中缀表达式
2.1 遇到数字时加入后缀表达式
2.2 遇到运算符时,根据优先级判断
2.2.1 遇到"("入栈
2.2.2 遇到")"则依次将栈中的运算符加入后缀表达式,直到出现"(",从栈中删除"("
2.2.3 除括号外的其他运算符,当其优先级高于'('外的栈顶运算符,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和相等的运算符,直到一个比它优先级低的或遇到一个左括号为止。
3. 扫描结束时,栈中的所有运算符依次出栈加入后缀表达式。
  • 表达式求值:使用后缀表达式
1. 遇到操作数则进栈
2. 遇到操作符,栈中前两个元素退栈,进行计数后的结果入栈
3. 扫描处理完成后,栈顶存放的就是最后的计算结果
  • 在递归中的应用

优点:代码简单,容易理解。

缺点:递归次数过多容易造成栈溢出,递归调用过程包含很多重复计算,效率不高

  • 进制转换
  • 迷宫求解
大题
  1. 判断一个序列是否是合法序列(初态和终态均为空)。
int Judge(char A[]){
    int i=0;
    int j=k=0;
    while(A[i]!='\0'){
        switch(A[i]){
            case 'I': j++; break;
            case 'O': k++;
                if(k>j){
                    printf('序列非法\n');
                    exit(0);
                }
        }
        i++;
    }
    if(j!=k){
        printf('序列非法\n');
        return false;
    }else{
        printf('序列合法\n');
        return true;
    }
}
  1. 判断链表的全部n个字符是否中心对称
//思路:先将一半元素进栈。n为偶数,比较前一半和后一半;n为奇数,指针跳到下一个字符开始比较。
int dc(LinkList L, int n){
    int i;
    char s[n/2];
    p=L->next;
    for(i=0;i<n/2;i++){
        s[i]=p->data;
        p=p->next;
    }
    i--;
    if(n%2==1)
        p=p->next;
    while(p!=NULL&&s[i]==p->data){
        i--;
        p=p->next;
    }
    if(i==-1)
        return 1;
    else
        return 0;
}
  1. 有两个栈s1、s2都采用顺序栈方式,并共享一个存储区[0,…,maxsize-1],采用栈顶相向,迎面增长的存储方式,设计s1、s2有关入栈和出栈的操作算法。
//入栈
int push(int i,elemty x){
    //i为栈号,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.stack[++s.top[0]]=x; return 1; break;
        case 1:s.stack[--s.top[1]]=x; return 1;
    }
}
//出栈
elemtp pop(int i){
    if(i<0||i>1){
        printf("栈号输入错误");
        exit(0);
    }
    switch(i){
        case 0:
            if(s.top[0]==-1){
                printf("栈空\n");
                return -1;
            }
            else
                return s.stack[s.top[0]]--;
        case 1:
            if(s.top[1]==maxsize){
                printf("栈空\n");
                return -1;
            }
            else
                return s.stack[s.top[1]]++;
    }
}
  1. 假设一个算术表达式中包含圆括号、方括号和花括号3中类型的括号,编写一个算法来判别表达式中的括号是否配对,以字符“\n”作为表达式的结束符。
bool BracketsCheck(char *str){
    InitStack(S);
    int i=0;
    while(str[i]!='\n'){
        switch(str[i]){
            case '(': Push(S,'('); break;
            case '[': Push(S,'['); break;
            case '{': Push(S,'{'); break;
            case ')': Pop(S,e);
                if(e!='(') return false;
				break;
            case ']': Pop(S,e);
                if(e!='[') return false;
				break;
            case '}': Pop(S,e);
                if(e!='{') return false;
				break;
            default:
                break;
        }
        i++;
    }
    if(!IsEmpty(S)){
        printf("括号不匹配\n");
        return false;
    }else{
        printf("括号匹配");
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一刻不学习就是15分钟

对您有用就行,别钱不钱的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值