<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>汉诺塔 on kenji.blog</title><link>http://kenji.blog/zh-cn/tags/%E6%B1%89%E8%AF%BA%E5%A1%94/</link><description>Recent content in 汉诺塔 on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>kenjinote</copyright><lastBuildDate>Thu, 17 Apr 2025 22:23:14 +0900</lastBuildDate><atom:link href="http://kenji.blog/zh-cn/tags/%E6%B1%89%E8%AF%BA%E5%A1%94/index.xml" rel="self" type="application/rss+xml"/><item><title>汉诺塔</title><link>http://kenji.blog/zh-cn/p/%E3%83%8F%E3%83%8E%E3%82%A4%E3%81%AE%E5%A1%94/</link><pubDate>Thu, 17 Apr 2025 22:23:14 +0900</pubDate><guid>http://kenji.blog/zh-cn/p/%E3%83%8F%E3%83%8E%E3%82%A4%E3%81%AE%E5%A1%94/</guid><description>&lt;img src="http://kenji.blog/p/%E3%83%8F%E3%83%8E%E3%82%A4%E3%81%AE%E5%A1%94/img.png" alt="Featured image of post 汉诺塔" />&lt;h1 id="汉诺塔">汉诺塔
&lt;/h1>&lt;p>你好！&lt;/p>
&lt;p>今天，我想一边展示Python的示例程序，一边为大家讲解“汉诺塔”。&lt;/p>
&lt;hr>
&lt;h2 id="什么是汉诺塔">什么是汉诺塔？
&lt;/h2>&lt;p>汉诺塔是一个使用3根柱子和多个圆盘的益智游戏。圆盘大小不一，最初按照从大到小的顺序堆叠在一根柱子上。规则如下：&lt;/p>
&lt;ol>
&lt;li>每次只能移动1个圆盘。&lt;/li>
&lt;li>较小的圆盘上不能放置较大的圆盘。&lt;/li>
&lt;/ol>
&lt;p>这个益智游戏被认为是学习递归思维的最佳教材。递归是一种将某个问题分解为同类型的较小问题来解决的方法。在汉诺塔中，为了移动n个圆盘，我们会重复执行移动n-1个圆盘的操作。&lt;/p>
&lt;hr>
&lt;h2 id="让我们用python来解汉诺塔">让我们用Python来解汉诺塔
&lt;/h2>&lt;p>以下是用Python解汉诺塔的示例代码。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">source&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">auxiliary&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Move disk 1 from &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">source&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> to &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">target&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">source&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">auxiliary&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Move disk &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> from &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">source&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> to &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">target&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">auxiliary&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">source&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 示例：将3个圆盘从A移动到C&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;A&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;C&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;B&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>在这段代码中，&lt;code>hanoi&lt;/code> 函数被递归调用，并输出移动圆盘的步骤。例如，在有3个圆盘的情况下，会得到以下输出：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">Move disk 1 from A to C
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 2 from A to B
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 1 from C to B
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 3 from A to C
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 1 from B to A
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 2 from B to C
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 1 from A to C
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>像这样，通过使用递归方法，复杂的问题也能简单地解决。&lt;/p>
&lt;hr>
&lt;h2 id="移动64个圆盘需要多长时间">移动64个圆盘需要多长时间？
&lt;/h2>&lt;p>汉诺塔的移动次数至少需要 2^n - 1 次。也就是说，要移动64个圆盘，需要 2^64 - 1 次，大约 1.84×10^19 次移动。即使每秒移动一次，大约也需要5849亿年。这大约是宇宙年龄（约137亿年）的42倍。&lt;/p>
&lt;p>像这样，随着圆盘数量的增加，所需的移动次数呈指数级增长。因此，在现实中移动64个圆盘是不切实际的。&lt;/p>
&lt;hr>
&lt;h2 id="总结">总结
&lt;/h2>&lt;p>汉诺塔是学习递归思维的最佳益智游戏。使用Python，可以轻松实现其解法。然而，随着圆盘数量的增加，所需的移动次数会急剧增加，因此需要注意。&lt;/p>
&lt;p>通过理解递归方法并实际编写代码，可以提高编程技能。请务必挑战一下汉诺塔。&lt;/p>
&lt;hr></description></item></channel></rss>