碎碎念


在大一学习C语言的时候,举过一个用栈实现的括号匹配算法,当时觉得很难,不过现在回顾起来,这个算法也算是比较简单的一个关于栈的应用了。而现在所常见的算法问题也都是什么中缀表达式转后缀表达式,双栈找最小值之类的。难度比之括号匹配稍有提升,不过倒也算是必须要掌握的算法。

上述所说的表达式求值在程序设计语言中是一个最基本的问题,也是栈的实现的一个典型范例。

为什么说是最基本? 我们知道,中缀表达式对于人来说是比较友好的,学过四则运算就可以对其求值,然而对于计算机来说,虽然也可以想办法计算,但是却算不上友好了;相反,后缀表达式虽然对人不友好,但是却是计算机所喜欢的。

(话说,后缀表达式在编译原理中的重要性也是能栖身前列的。)


在C语言入门的时候,我们就会通过递归来求斐波那契数列,很简单:

int fibonacci(int n) {if (n==0 || n==1) return 1;return fibonacci(n-1) + fibonacci(n-2);
}
复制代码

但是那时候还不懂原理,仅仅知道,递归就是函数调用其本身,但是接触到数据结构的时候,再一次提出了递归的概念。

什么是递归?递归就是函数调用其本身

reverse(know) {  // 1. go onif (you know) return you know; // 2. look 4else back to see the 1; // 3. go back to 1.
} // 4. you know what is recurision now.
复制代码

这时候,我们不仅知道递归真正的用法,同时也知道了一个事实,即递归程序的开销通常很大,但与之相反的,其代码量又是非常少的。

通常情况下,我们会选择将递归程序改写成非递归程序,即所谓消除递归,但是当改写后和改写前的程序并不会有太大的性能提升,我们也没有必要去改写,比如:cout << fibonacci(5); ,为了这样的调用去消除递归,有必要吗?

可实际情况是,一个应用所要处理的数据并不算小,消除递归是不可避免的。

递归的精髓在于能否将原始的问题转换为属性相同,但问题规模较小的问题,学过算法就知道,这同样也是贪心策略和动态规划的本质。

优化

对于递归程序的优化,我们通常会选择栈做辅助,为什么?我们知道,在操作系统中,有一种叫做**“函数调用堆栈”**的名词,大概的解释就是:当在某一函数A中调用另一函数B时,我们将A中的内容保存后,压入系统堆栈(你可以说这是在创建还原点,也可以说这个是现场保护,开心就好。),然后执行函数B的内容,当函数B执行结束后,将A从系统堆栈中弹出,继续从断点处执行,同时销毁之前申请的栈空间。

同时,我们要知道,操作系统的主存是由空间上限的,不可能是无限的。系统堆栈的大小自然是受操作系统存储空间大小的约束的,而且绝对小于系统存储空间(不可能等于)。所以,当递归程序不断申请栈空间到达系统栈所能分配的上限时,就有了所谓的“系统堆栈溢出”,即我们通常所说的“爆栈”。

  • 斐波那契函数n=6时,递归调用树
  • n=3时,栈的申请情况

  • n=6时,栈的申请情况

java中,异常java.lang.StackOverflowError就是一种堆栈溢出错误,不过,可以通过修改JVM参数来增大虚拟机栈空间,如-vm args-Xss128k;但这也只是权宜之计,治标不治本呐。

但是呢,一个递归程序并不一定非要用栈辅助改写成非递归程序(即消除递归),有时候,一个循环就够了。

int main() {int n, i=j=1, tmp=0;cin >> n;while (n--) {tmp = i+j;i = j;j = tmp;}
}
复制代码

暂时就说这么多,至于后面的,那就后面再说吧,毕竟这也只是(一)嘛。

数据结构碎碎念(一)相关推荐

  1. 9月碎碎念-谈如何挑选一本书

    总第170篇/张俊红 每月一篇的碎碎念又来了,这一篇谈谈『如何挑选一本书』,之前在公众号提过,挑书也是一种能力,有的人买书之前不仔细看这本书到底适合不适合自己,或者是说还没想清楚买这本书的目的是什么, ...

  2. Rust 与服务端编程的碎碎念

    Rust 与服务端编程的碎碎念 https://zhuanlan.zhihu.com/p/30028047 Rust 是 Mozilla 推出的一门系统编程语言,非常看重内存安全,是一门非常优秀的语言 ...

  3. 数据分析+数据挖掘暑期实习碎碎念

    写在前面 在闺蜜的博客乱写一篇关于最近春招的心得! 先念念叨一点麻痹自我的鸡汤. 鸡汤说:要有最朴素的生活与最遥远的梦想,即使明日天寒地冻,路遥马亡. 鸡汤还说:慢慢走比较快:踏实一点,你想要的岁月都 ...

  4. 每月碎碎念 | 2019.6

    Hi,这里是新开辟的"碎碎念"的板块. 这个区域作为记录心情的地方,把每日的所思所想所感所悟以及看到的比较有价值的文字记录在这里,当做一个写日记,分享价值的地方,每个月底汇总成一篇 ...

  5. 前端碎碎念 之 nextTick, setTimeout 以及 setImmediate 三者的执行顺序

    『前端碎碎念』系列会记录我平时看书或者看文章遇到的问题,一般都是比较基础但是容易遗忘的知识点,你也可能会在面试中碰到. 我会查阅一些资料并可能加上自己的理解,来记录这些问题.更多文章请前往我的个人博客 ...

  6. 参加海峡两岸城市地理信息系统论坛2010 年会(一张图、规划信息化和空间句法的碎碎念)...

    上周末去清华建筑学院开了个会,叫做海峡两岸城市地理信息系统论坛2010 年会,主题很大,但是内容比较集中一些,就是围绕着GIS与城市规划.一天下来听了20个报告,挺佩服主办方的时间控制,这么密集的报告 ...

  7. Jerry的碎碎念:SAPUI5, Angular, React和Vue

    2019独角兽企业重金招聘Python工程师标准>>> 去年我去一个国内客户现场时,曾经和他们IT部门的一位架构师聊到关于在SAP平台上进行UI应用的二次开发时,UI框架是选用UI5 ...

  8. PMcaff写给大家的年终碎碎念 PMcaff | 记录

    今天是大年三十,2014马上就要结束了,送上新春祝福之前,碎碎念的小希有话想跟大家说. 瞧这一年 小米在硬件行业继续如鱼得水,科幻片里的智能家居生慢慢变成生活. 阿里巴巴在纳克达斯扬眉吐气了一把,一夜 ...

  9. 机器学习碎碎念:霍夫丁不等式

    点击上方"AI有道",选择"设为星标" 关键时刻,第一时间送达! 红色石头每天碎碎念一些机器学习知识和概念,大家一起学习,每天进步一点点!喜欢的话别忘了文末点赞 ...

最新文章

  1. 卷积神经网络:VGG16 是基于大量真实图像的 ImageNet 图像库预训练的网络
  2. 弄懂CNN,然后提升准确率4.21-4.27
  3. 计算机表格中如何计算数据透视表,在数据透视表中计算值
  4. 如何在工作中如鱼得水?有三点很重要
  5. 国产环境小卫星数据预处理及简单应用
  6. java infinite or nan,java.lang.NumberFormatException: Infinite or NaN(数学运算错
  7. 事业单位资产管理系统破解资产管理难题,实现账、卡、物、地、人相符
  8. 基于redis实现活跃用户统计功能
  9. smartbi v7 Linux,Smartbi V7.0.1
  10. 初识ArrayList集合【小白学Java-学习笔记02】
  11. win10添加打印机失败,无法正常使用打印机的解决办法
  12. Python入门必学,用Python练习画个美队盾牌
  13. python提取cad中的文字_[python]提取PPT中的文字(包括图片中的文字)
  14. 14015problem I 方案数
  15. 行式 Excel 文件拆分
  16. 基于惯性动作捕捉技术进行快速动画制作教程
  17. 智慧社区系统开发,智慧社区平台搭建解决方案
  18. 06 RGB和BGR颜色空间
  19. 中国储物篮市场运营状况及投资经营分析报告 2022-2027年版
  20. matlab 确定参数 一钓鱼俱乐部,Matlab常用命令{1}.doc

热门文章

  1. 阿里巴巴矢量图标库iconfont的使用
  2. DataGridView中实现点击单元格Cell动态添加自定义控件
  3. SSH连接服务器报错(WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED)的解决方案
  4. Flutter:Stream.periodic 示例
  5. php 特殊字符大全,关于php 特殊字符的文章推荐
  6. etc的常见算法_谈常用的几个机器学习算法,学懂算法也可以这么简单!
  7. 神策数据:从技术视角看,如何更多、更好、更快地实施A/B试验
  8. 直播预告丨B2B 企业如何高效获客增长?
  9. 感知重塑与忠诚建立:车企营销的两大新机遇
  10. Node.Js从零开始搭建数据管理后台 (一)