程序猿必修课之数据结构(七)栈2

原文:http://www.jianshu.com/p/5728607674e4

你还在为开发中频繁切换环境打包而烦恼吗?快来试试 Environment Switcher 吧!使用它可以在app运行时一键切换环境,而且还支持其他贴心小功能,有了它妈妈再也不用担心频繁环境切换了。https://github.com/CodeXiaoMai/EnvironmentSwitcher

上一章:程序猿必修课之数据结构(六)栈1

栈的应用——递归

斐波那契(Fibonacci)是一个经典的递归例子。

斐波那契数列

数字 1,1,2,3,5,8,13......构成一个序列,它的特点是:前面相邻两项之和是后一项的值。用数学函数来定义是:

斐波那契数列

用递归实现打印出前 40 位的斐波那契数列数的代码如下:

# include<stdio.h>

int Fbi(int);

int main() {
    int i;
    for (i = 0; i < 40; i++) {
        printf("%d ", Fbi(i));
    }
    return 0;
}

int Fbi(int i) {
    if (i == 0)
        return 0;
    if (i == 1)
        return 1;
    /* 函数调用自己 */
    return Fbi(i - 1) + Fbi(i -2);
}

函数调用自己,可以理解为调用另一个函数,只不过,这个函数和自己一样而已。

递归的定义

一个直接或通过一系列的调用语句间接的调用自己的函数,称为递归函数。

每个递归定义必须至少有一个条件满足时递归不再进行,即不再调用自己而是返回值并退出。

迭代和递归的区别

迭代使用的是循环结构,递归使用的是选择结构。递归能使程序的结构更清晰、更简洁、更容易理解,但是大量的递归调用会耗费大量的时间和内存。迭代则不需要反复调用函数和占用额外的内存。所以,凡事都有利有弊,我们应该视情况选择合适的方式。

栈的应用——四则运算表达式求值

后缀(逆波兰)表示法

对于"9 + (3 -1)X 3 + 10 ÷ 2" ,如果要用后缀表示法应该是"9 3 1 - 3 * + 1 0 2 / +",这样的表达式称为后缀表达式,叫后缀的原因在于所有的符号都是在要运算数字的后面出现。

我们把平时所用的标准四则运算表达式 ,即 9 + ( 3-1 ) X 3 + 10 ÷ 2 叫做中缀表达式,因为所有的运算符号都在两数字的中间。那么如何将中缀表达式转换为后缀表达式呢?

中缀表达式转后缀表达式

中缀表达式转后缀表达式的规则是:

从左到右遍历中缀表达式的每个数字和符号,若是数字就输出;若是符号,就判断其与栈顶符号的优先级,如果是右括号或者优先级低于栈顶符号,则栈顶元素依次出栈并输出,再将当前符号进栈......直到最终输出后缀表达式为止。

按照上面的规则,把 9 + ( 3 - 1 ) X 3 + 10 ÷ 2 转换为后缀表达式

用 temp 表示当前输出过的所有内容,用 stack 表示存储运算符的栈。

  1. 第一个字符是数字 9,temp = "9";后面是符号“+”进栈,stack = "+";
  2. 第三个字符是“(”,因为它是左括号,所以进栈,stack = "+ (";
  3. 第四个字符是数字 3,所以 temp = "9 3";后面是符号“-”进栈,stack = “+ ( -”;
  4. 第六个字符是数字 1,所以 temp = "9 3 1";后面是“)”,所以我们要把 stack 中的栈顶符号出栈,直到“(”出栈为止。因为“(”上面只有一个“-”,所以输出“-”,temp = “9 3 1 -”,stack = "+";
  5. 第八个字符是“X”,此时栈顶符号为“+”,优先级比“X”低,所以“X”进栈,stack = “+ *”;
  6. 第九个字符是数字 3,所以 temp = “9 3 1 - 3";
  7. 第十个字符是“+”,此时栈顶元素为“ * ”比“+”的优先级高,所以栈顶元素出栈并输出(没有比“+”更低的优先级,所以全部出栈)然后再将“+”入栈,temp = "9 3 1 - 3 * +",stack = "+";
  8. 第十一个字符是数字10,temp = "9 3 1 - 3 * + 10",后面是符号“÷”,所以“/"入栈,stack = "+ /";
  9. 最后一个字符是数字2,temp = "9 3 1 - 3 * + 10 2";
  10. 因为已经到了最后,所以将栈中符号全部出栈并输出,temp = "9 3 1 - 3 * + 10 2 / +"; stack 为空栈,结束。

所以 9 + ( 3 - 1 ) X 3 + 10 ÷ 2 转换为后缀表达式结果为 temp 的值"9 3 1 - 3 * + 10 2 / +"。

后缀表达式计算方法

规则:从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到符号就将处于栈顶的两个数字出栈进行运算;再将运算结果进栈,直到遍历结束。

求后缀表达式 "9 3 1 - 3 * + 10 2 / +"的值:

用 stack 表示存储符号的栈。

  1. 因为后缀表达式的前 3 个字符都是数字,所以“9 3 1”依次进栈,stack = “9 3 1”;
  2. 接下来是“-”,所以将栈顶的“1”出栈作为“减数”,再将“3”出栈作为“被减数”,计算 3 - 1 = 2,再将 2 进栈,stack = “9 2”;
  3. 接着是数字 3 进栈,stack = “9 2 3”;
  4. 再接着是“*”,所以将栈顶的“3”出栈,再将“2”出栈,2 * 3 = 6;将 6 进栈,stack = “9 6”;
  5. 后面是“+”,将栈中6 和 9 出栈并相加得到 15,将15进栈,stack = “15”;
  6. 接着是数字10 和 2,将它们依次进栈,stack = “15 10 2”;
  7. 后面是“/”,将 2 出栈作为除数,再将 10 出栈作为被除数,10 / 2 = 5,将 5 进栈,stack = "15 5";
  8. 最后一个符号是“+”,所以将 15 与 5 相加得到 20,再将 20 入栈,stack = “20”;
  9. 此时,已经没有符号了,所以将栈中的 20 出栈,运算结果为 20。

总结

  1. 将中缀表达式转为后缀表达式,栈用来存储运算符号。
  2. 计算后缀表达式的结果,栈用来存储运算的数字。

下一章:程序猿必修课之数据结构(八)队列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容