=>  递归算法即递归函数调用自身的过程,递归的过程背后就是函数调用的过程!

 

1. 函数调用的背后过程

 

任何一段代码、任何一个程序调用之前,系统都会开辟一个函数调用栈。用这个栈来保存各个函数在调用过程当中所必须保存的一些信息。包括:调用返回地址、实参、局部变量

 

【2】9 栈在递归中的应用

程序的入口是 main 函数,刚开始运行 main 函数的时候,会把 main 函数相关的一些必要信息压入栈中,比如 main 函数里面的局部变量 a、b、c。

为了保证程序运行顺序的正确性 (从计算机的思维),会在调用 funct 1 这个函数的时候,把func 1 执行结束之后应该执行的代码的存储地址(#1) 压入栈中。    除此之外,函数调用的两个参数 (a,b) 也会压入栈中。所以这也是为什么当调用函数的时候,可以将一个 视为“原件” ,一个视为“复印件”  (比如 func 1 中修改 a,b 的值,其实修改是另一内存中 a,b 的值, main 函数里面的 a,b 值并不受影响)       除了被调用函数的实参之外,该函数定义的局部变量 x 也会压入栈中。   

func 2 函数调用过程类似分析。 当 func 2 函数执行完了之后,会根据栈顶地址信息( #2 ) 找到下一句将执行的代码, 然后将 func 2 函数相关的信息弹出栈!(即释放 func 2 占用的内存空间),当 func 1  函数执行完后,同样会根据栈顶地址信息( #12 ) 找到下一句将执行的代码, 然后将 func 1 函数相关的信息弹出栈!然后执行 main 函数剩下的代码!

 

从我们的视角来看,程序是从 main 函数开始执行的,但其实程序在经过编译之后,编译器会在 main 函数之前还加一些其它的代码,那些代码执行完了之后,才会调用 main 函数,执行 main 函数相关的东西。(上面的栈图中 main 函数之前有一些 ..... )

小结:只要涉及到函数调用背后就要栈的支持。

 

IDE中通过 debug 方式可以进行观察函数调用栈中保存了哪些东西。

【2】9 栈在递归中的应用

 

 

 

 

2. 栈在递归问题中的使用

很多问题都可以用递归的方式来解决,这类问题的特点是: 可以把原始问题转换为 属性相同、但规模较小的问题。

 

【2】9 栈在递归中的应用

这里的重点的并不是如何设计一个递归算法,而是这个递归算法它背后和栈有什么联系。

 

 

【2】9 栈在递归中的应用

 

【2】9 栈在递归中的应用

 

缺点:太多层递归可能导致栈溢出!(比如这里计算 100000! )
           递归算法的空间复杂度 !!!

 

【2】9 栈在递归中的应用

 

【2】9 栈在递归中的应用

 

 

相关文章:

  • 2021-05-05
  • 2021-08-08
  • 2021-10-08
  • 2022-12-23
  • 2022-12-23
  • 2021-07-02
猜你喜欢
  • 2022-12-23
  • 2021-12-09
  • 2021-08-22
  • 2021-05-07
  • 2021-11-02
  • 2021-06-19
  • 2022-12-23
相关资源
相似解决方案