数据结构3 - 栈与队列


一、栈

先进后出(FILO)、后进先出(LIFO)

1、栈接口与实现
  • 基本接口
    • size() / empty() 大小/是否空
    • push() 入栈
    • pop() 出栈
    • top() 查顶
2、调用栈:原理与算法

尽量少些递归程序,即少使用系统级的栈调用,会有很多不必要的损耗,只需要将必要的数据调用栈即可。

3、调用栈:尾递归

尾递归是不必要的,可以改成循环。

4、进制转换(十进制转其他进制)

每次模余,将余数存入栈内,模余之后除以转换的进制数,进入下一次循环,直到除数为0循环结束,将栈输出即是要转换的进制

5、括号匹配

遇到左括号进栈,遇到右括号则查看栈顶元素,是否是同类型的左括号,若是,则出栈;若不是,则括号不匹配。全部遍历完成后,栈未空则括号匹配。

//假设字符串内只有括号且只有一种括号
bool paren(const char exp[], int lo, int hi){ //exp[lo, hi)
    Stack<char> S; //使用栈记录一发现但尚未匹配的左括号
    for(int i = lo;i < hi; i++){ //逐一检查当前字符
        if('(' == exp[i]) S.push(exp[i]); //遇左括号:则进栈
        else if(!S.empty()) S.pop(); //遇到右括号:若栈非空,则弹出左括号
        else return false; //否则(遇右括号时栈已空),必不匹配
    }
    return S.empty(); //最终栈空,当且仅当匹配
}

/*
	若只有一种括号,只需要一个计数器就可,初始值为0,遇左括号加1,遇右括号减1,最后计数器为0则匹配
*/
6、中缀表达式求值
float evaluate(char *S, char *&RPN){ //S保证语法正确
    Stack<float> opnd; Stack<char> optr; //运算数栈、运算符栈
    optr.push('\0'); //铺垫
    while(!optr.empty()){ //逐个处理各字符,直至运算符为空
        if(isdigit(*S)) //若为操作数(可能多位、小数),则
            readNumber(S, opnd); //读入
        else //若为运算符,则视其与栈顶运算符之间优先级的高低
            switch(orderBetween(optr.top(), *S))
            { /* 根据栈顶运算符和当前运算符的优先级比较,分别处理 */}
    }
    return opnd.pop(); //弹出并返回最后的计算结果
}
7、栈混洗

有三个栈A,B,S,其中B,S为空栈,只允许将A的顶元素弹出并压入S,或将S的顶元素弹出并压入B。若经一系列以上操作后,A中元素全部转入B中,则称为A的一个栈混洗。

  • 考察S在读变空(A首元素从S中弹出)的时刻,无非n种情况:

    SP(n) = catalan(n) = (2n)! / (n+1)! * n!

  • 对于任何1 < i < j < k <= n, […, k, …, i, …, j, …>必非栈混洗

8、双栈当队

用两个栈A,B实现队列,进队操作对栈B进行push,出队操作先判断栈A是否为空,为空则把栈B全部pop到栈A中,然后再pop 栈A;不为空直接pop 栈A 。

二、队列

先进先出(FIFO)、后进后出(LILO)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值