This commit is contained in:
krahets
2023-12-14 02:53:40 +08:00
parent 68eab8e7c1
commit a85d95787b
19 changed files with 156 additions and 156 deletions

View File

@ -3659,7 +3659,7 @@
<!-- Page content -->
<h1 id="22">2.2 &nbsp; 迭代与递归<a class="headerlink" href="#22" title="Permanent link">&para;</a></h1>
<p>在算法中,重复执行某个任务是很常见的,与复杂度分析息息相关。因此,在展开介绍时间复杂度和空间复杂度之前,我们先来了解如何在程序中实现重复执行任务,即两种基本的程序控制结构:迭代、递归。</p>
<p>在算法中,重复执行某个任务是很常见的,与复杂度分析息息相关。因此,在介绍时间复杂度和空间复杂度之前,我们先来了解如何在程序中实现重复执行任务,即两种基本的程序控制结构:迭代、递归。</p>
<h2 id="221">2.2.1 &nbsp; 迭代<a class="headerlink" href="#221" title="Permanent link">&para;</a></h2>
<p>「迭代 iteration」是一种重复执行某个任务的控制结构。在迭代中程序会在满足一定的条件下重复执行某段代码直到这个条件不再满足。</p>
<h3 id="1-for">1. &nbsp; for 循环<a class="headerlink" href="#1-for" title="Permanent link">&para;</a></h3>
@ -4960,11 +4960,11 @@
<p class="admonition-title">Tip</p>
<p>如果感觉以下内容理解困难,可以在读完“栈”章节后再来复习。</p>
</div>
<p>那么,迭代和递归具有什么内在联系呢?以上述递归函数为例,求和操作在递归的“归”阶段进行。这意味着最初被调用的函数实际上是最后完成其求和操作的,<strong>这种工作机制与栈的“先入后出”原则异曲同工</strong></p>
<p>那么,迭代和递归具有什么内在联系呢?以上述递归函数为例,求和操作在递归的“归”阶段进行。这意味着最初被调用的函数实际上是最后完成其求和操作的,<strong>这种工作机制与栈的“先入后出”原则异曲同工</strong></p>
<p>事实上,“调用栈”和“栈帧空间”这类递归术语已经暗示了递归与栈之间的密切关系。</p>
<ol>
<li><strong></strong>:当函数被调用时,系统会在“调用栈”上为该函数分配新的栈帧,用于存储函数的局部变量、参数、返回地址等数据。</li>
<li><strong></strong>:当函数完成执行并返回时,对应的栈帧会从“调用栈”上移除,恢复之前函数的执行环境。</li>
<li><strong></strong>:当函数完成执行并返回时,对应的栈帧会从“调用栈”上移除,恢复之前函数的执行环境。</li>
</ol>
<p>因此,<strong>我们可以使用一个显式的栈来模拟调用栈的行为</strong>,从而将递归转化为迭代形式:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="8:12"><input checked="checked" id="__tabbed_8_1" name="__tabbed_8" type="radio" /><input id="__tabbed_8_2" name="__tabbed_8" type="radio" /><input id="__tabbed_8_3" name="__tabbed_8" type="radio" /><input id="__tabbed_8_4" name="__tabbed_8" type="radio" /><input id="__tabbed_8_5" name="__tabbed_8" type="radio" /><input id="__tabbed_8_6" name="__tabbed_8" type="radio" /><input id="__tabbed_8_7" name="__tabbed_8" type="radio" /><input id="__tabbed_8_8" name="__tabbed_8" type="radio" /><input id="__tabbed_8_9" name="__tabbed_8" type="radio" /><input id="__tabbed_8_10" name="__tabbed_8" type="radio" /><input id="__tabbed_8_11" name="__tabbed_8" type="radio" /><input id="__tabbed_8_12" name="__tabbed_8" type="radio" /><div class="tabbed-labels"><label for="__tabbed_8_1">Python</label><label for="__tabbed_8_2">C++</label><label for="__tabbed_8_3">Java</label><label for="__tabbed_8_4">C#</label><label for="__tabbed_8_5">Go</label><label for="__tabbed_8_6">Swift</label><label for="__tabbed_8_7">JS</label><label for="__tabbed_8_8">TS</label><label for="__tabbed_8_9">Dart</label><label for="__tabbed_8_10">Rust</label><label for="__tabbed_8_11">C</label><label for="__tabbed_8_12">Zig</label></div>
@ -5224,12 +5224,12 @@
</div>
</div>
</div>
<p>观察以上代码,当递归被转换为迭代后,代码变得更加复杂了。尽管迭代和递归在很多情况下可以互相转,但不一定值得这样做,有以下两点原因。</p>
<p>观察以上代码,当递归转化为迭代后,代码变得更加复杂了。尽管迭代和递归在很多情况下可以互相转,但不一定值得这样做,有以下两点原因。</p>
<ul>
<li>转化后的代码可能更加难以理解,可读性更差。</li>
<li>对于某些复杂问题,模拟系统调用栈的行为可能非常困难。</li>
</ul>
<p>总之,<strong>选择迭代还是递归取决于特定问题的性质</strong>。在编程实践中,权衡两者的优劣并根据情境选择合适的方法至关重要</p>
<p>总之,<strong>选择迭代还是递归取决于特定问题的性质</strong>。在编程实践中,权衡两者的优劣并根据情境选择合适的方法至关重要。</p>
<!-- Source file information -->