神奇的汉诺塔

  • 嘿,不知道大伙儿是否还记得汉诺塔呢?如果忘记了,没关系,我会先帮大家回忆下大学里美好的数据结构课程。
    第一步,回忆下这门课程的封面&:
神奇的汉诺塔_第1张图片
神奇的数据结构
  • 嗯,没错,就是它了。
    之后,就是描述下汉诺塔了(请原谅我要去百度了。。。):
    汉诺塔(又称河内塔),是根据一个传说形成的数学问题,有三根柱子A,B,C。A杆上有N(N>1)个穿孔原盘,盘的尺寸由下到上依次变小,估计长这样:
神奇的汉诺塔_第2张图片
一坨汉诺塔

(黄色的一坨么?execuse me。。。)
现在,要按照如下的规则将所有的原盘移至C杆中:
1. 每次只能移动一个原盘;
2. 大盘不能叠在小盘上面;
3. 可将原盘临时置于B杆,但必须遵循上述两条规则。

好了,规则就是这样,现在,小伙伴们,要怎样移动呢?

  • 作为一个程序员,应该具备一些基本的思想,比如二分,比如数学归纳(其实就是递归),比如。。。(to be honest,我不知道还有啥,有知道的请留言)。
    对于汉诺塔而言,我最先想到的,就是用递归去做。怎么做呢?
    要使用递归,需要两个步骤:
    1. 找出终止条件;
    2. 建立数学表达式。

  • 那我们首先做第一步。(这里将A上的原盘做编号,从上到下依次为1,2,3,...)

    • 当n=1时,直接移动到C。
      至此,我们完成了第一步。
      是的,一切就是这么简单。

    • 当n=2时:


      神奇的汉诺塔_第3张图片
      n==2

      1.将1由A移至B;
      2.将2由A移至C;
      3.将1由B移至C。
      嗯,换种说法:
      1.将1移至起过渡作用的B柱上;
      2.将2移至最后目标(结果)的C柱上;
      3.将1移动到目标(结果)的C上。

    • n=3时:


      神奇的汉诺塔_第4张图片
      n==3

      ps:该图中的B是作为最后结果存在的,C是作为过渡作用的柱子

      1)1移至B;
      2)2移至C;
      3)1移至C;
      4)3移至B;
      5)1移至A;
      6)2移至B;
      7)1移至B;
        ...
      

    这样想,是不是还是很复杂,那我们换个方式。
    1)将1和2 按照 n=2时的移动步骤进行移动(完成后,对应上图中的第三个步骤)
    2)将3移动到B(上图中的第四个步骤),
    3)将1和2移动到B(上图中的5,6,7)。
    这样想是不是简单多了呢?

    • 现在通过对柱子的命名来做进一步的抽象描述。
      初始状态时,对应的三个柱子的作用是这样的:


      神奇的汉诺塔_第5张图片
      hannoi1.png
    • 当移动了1和2后,三根柱的作用变成了这样:


      神奇的汉诺塔_第6张图片
      hanoi2.jpg
  • 这样就清晰明了了。
    那么就可以这样描述了:
    1)将n=(3-1)的圆盘通过过渡柱和结果柱,移动到过渡柱;
    2)将n=3的圆盘移动到结果柱;
    3)将n=(3-1)的圆盘通过过渡柱和起始柱,移动到结果柱。

  • 好了,说了这么多,我们来总结下使用递归解汉诺塔的第二个步骤,建立数学表达式:
    f(1) = 1
    f(n) = f(n-1) + 1 + f(n-1)

    1.f(n-1)对应的操作:将n-1-1从起始柱移动到过渡柱;
    2.1对应的操作:将该圆盘移动到结果柱;
    3.f(n-1)对应的操作(柱子的命名一定):将过渡柱上的圆盘,经过过渡柱移动到结果柱。
    
  • 至此,汉诺塔的移动操作全部完成

  • 由于 talk is cheap, 故附上使用递归完成的code:

    神奇的汉诺塔_第7张图片
    show me the code

  • 源代码

*enjoy coding , enjoy life *

你可能感兴趣的:(神奇的汉诺塔)