一句话概括:递归是一样的代码,不一样的栈空间(对应不一样的数据)!
了解了进程栈、线程栈、函数栈和进程代码段的基础知识(可参见我的相关博客)之后,再看函数,就不再是函数,而是一个个的栈空间!
再看递归函数,看到的是递归函数每次调用自身(我管它是不是自身呢!)都会开辟一个栈空间。递归调用就是循环地产生很多同样结构的栈空间——只是各层栈空间里面保存的数据不一样而已。
因此可以总结下:
递归就是数据不同,但是处理相同,栈记录不同的数据,代码段是同一份。——这也是递归可以改成for循环的原因。
递归函数的运行是从上往下盖很多层栈空间(可以想象成楼房),把每层的数据压到对应层的房间里,直到出口点,不盖房了,这个时候就开始从下往上地挨个处理各房间保存的数据——处理相同哦!
也就是说,递归函数每一次调用自身都会开辟一个栈空间,把不同的数据存到不同栈空间,所以我说栈记录不同的数据。
而这开辟栈的操作都是同一份代码,就好像在原地转圈圈,但是开辟了很多栈空间,等到递归回来的时候又毁灭掉一个个的栈空间。
了解了进程栈、线程栈、函数栈和进程代码段的基础知识后,提到递归就不再停留在“自己调用自己”的层次上了,而是应该头脑有画面——栈空间不断开辟和销毁的画面。
其实应该画个图,进行图形化讲解。
改天有空画画图,其实对于新人来说直接搜索入栈出栈的基础知识加图形绘画,再结合递归就能明白了。
递归应该属于栈的知识板块。
将递归与栈结合下即可明白递归是个什么玩意儿。
递归理解层次:
第一层次:浮于表面的似懂非懂的教科书上的死记硬背的“递归是自己调用自己”。
第二层次:递归是同一份代码开辟不同栈空间保存不同数据,按递归层次对不同栈空间里不同的数据进行相同的处理。——缺少动态图。
关键点
1.不同递归层次的数据放到对应层次的栈空间。
2.对栈空间保存的数据处理流程一致——即重复处理是循环和递归诞生的基石和根本。
3.递归就是对不同数据的搜索和分别处理,但处理都相同。处理这块是同一份代码,即cpu的pc指针从未离开过递归函数处理的那块代码,pc一直在这块代码里指来指去永不变(未达出口时),而变的只是栈空间里的数据!
4.递归不同层次的数据可以互相独立也可以有依赖关系,这倒无所谓,这不是重点,重点是递归的处理都是一样,即重复重复重复,重要的事情说三遍,重复是一大特点。
5.一句话概括:递归是一样的代码,不一样的栈空间! 你看一个个的栈空间都是执行同一份代码形成(开辟)的,然后我这同一份代码到各个栈空间去处理不同的数据!仅此而已!