mirror of
https://github.com/krahets/hello-algo.git
synced 2025-07-05 05:01:43 +08:00
Revised the book. (#987)
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
# 迭代与递归
|
||||
|
||||
在算法中,重复执行某个任务是很常见的,其与复杂度分析息息相关。因此,在展开介绍时间复杂度和空间复杂度之前,我们先来了解如何在程序中实现重复执行任务,即两种基本的程序控制结构:迭代、递归。
|
||||
在算法中,重复执行某个任务是很常见的,它与复杂度分析息息相关。因此,在介绍时间复杂度和空间复杂度之前,我们先来了解如何在程序中实现重复执行任务,即两种基本的程序控制结构:迭代、递归。
|
||||
|
||||
## 迭代
|
||||
|
||||
@ -173,12 +173,12 @@
|
||||
|
||||
如果感觉以下内容理解困难,可以在读完“栈”章节后再来复习。
|
||||
|
||||
那么,迭代和递归具有什么内在联系呢?以上述的递归函数为例,求和操作在递归的“归”阶段进行。这意味着最初被调用的函数实际上是最后完成其求和操作的,**这种工作机制与栈的“先入后出”原则是异曲同工的**。
|
||||
那么,迭代和递归具有什么内在联系呢?以上述递归函数为例,求和操作在递归的“归”阶段进行。这意味着最初被调用的函数实际上是最后完成其求和操作的,**这种工作机制与栈的“先入后出”原则异曲同工**。
|
||||
|
||||
事实上,“调用栈”和“栈帧空间”这类递归术语已经暗示了递归与栈之间的密切关系。
|
||||
|
||||
1. **递**:当函数被调用时,系统会在“调用栈”上为该函数分配新的栈帧,用于存储函数的局部变量、参数、返回地址等数据。
|
||||
2. **归**:当函数完成执行并返回时,对应的栈帧会从“调用栈”上被移除,恢复之前函数的执行环境。
|
||||
2. **归**:当函数完成执行并返回时,对应的栈帧会被从“调用栈”上移除,恢复之前函数的执行环境。
|
||||
|
||||
因此,**我们可以使用一个显式的栈来模拟调用栈的行为**,从而将递归转化为迭代形式:
|
||||
|
||||
@ -186,9 +186,9 @@
|
||||
[file]{recursion}-[class]{}-[func]{for_loop_recur}
|
||||
```
|
||||
|
||||
观察以上代码,当递归被转换为迭代后,代码变得更加复杂了。尽管迭代和递归在很多情况下可以互相转换,但也不一定值得这样做,有以下两点原因。
|
||||
观察以上代码,当递归转化为迭代后,代码变得更加复杂了。尽管迭代和递归在很多情况下可以互相转化,但不一定值得这样做,有以下两点原因。
|
||||
|
||||
- 转化后的代码可能更加难以理解,可读性更差。
|
||||
- 对于某些复杂问题,模拟系统调用栈的行为可能非常困难。
|
||||
|
||||
总之,**选择迭代还是递归取决于特定问题的性质**。在编程实践中,权衡两者的优劣并根据情境选择合适的方法是至关重要的。
|
||||
总之,**选择迭代还是递归取决于特定问题的性质**。在编程实践中,权衡两者的优劣并根据情境选择合适的方法至关重要。
|
||||
|
@ -760,7 +760,7 @@ $$
|
||||
|
||||
### 指数阶 $O(2^n)$
|
||||
|
||||
指数阶常见于二叉树。观察下图,高度为 $n$ 的“满二叉树”的节点数量为 $2^n - 1$ ,占用 $O(2^n)$ 空间:
|
||||
指数阶常见于二叉树。观察下图,层数为 $n$ 的“满二叉树”的节点数量为 $2^n - 1$ ,占用 $O(2^n)$ 空间:
|
||||
|
||||
```src
|
||||
[file]{space_complexity}-[class]{}-[func]{build_tree}
|
||||
|
Reference in New Issue
Block a user