汉诺(hanio)塔问题


规则:大盘子不能压在小盘子上。
要求:将A柱子上所有盘(每个盘大小不同)放到C柱子上,使用B柱子作辅助。


比如柱子A上有n个盘,执行以下步骤:
1. 把n-1个盘从源柱移动到临时柱上;
2. 把源柱上剩余的1个盘移动到目标柱上;
3. 把临时柱上的n-1个盘移到目标柱上。

显然,以上步骤将问题的规模缩小了一点。没有直接移动n个盘,而是移动n-1个盘。
那么,对于任务1和任务3来说,其性质显然和原问题是一样的,只是需要移动的盘子的数量减少了。
那么,对于任务1和任务3,可以用解决原问题的方法解决它们。这样不断重复下去,问题规模不断缩小,到最后变成了举手之劳,这样形成了递归模型。递归模型为hanio(int n, char source, char temp, char target)。num为当前任务需要移动的盘子的个数,source, temp, target用于指定三种类型的柱子。

为了写出代码,拿任务1作具体演绎:
1.1把n-1个盘从源柱移动到临时柱上;
  2.1把n-2个盘从源柱移动到临时柱上;
    3.1把n-3个盘从源柱移动到临时柱上;
      …
    3.2把源柱上剩余的1个盘移动到目标柱上;
    3.3把临时柱上的n-3个盘移到目标柱上。
  2.2把源柱上剩余的1个盘移动到目标柱上;
  2.3把临时柱上的n-2个盘移到目标柱上。
1.2把源柱上剩余的1个盘移动到目标柱上;
1.3把临时柱上的n-1个盘移到目标柱上。

 

移动是在两个位置之间移动,因此只需要两个参数。定义第一个参数位置始终为每个步骤的起点,第三个参数位置始终为每个步骤的终点。变量source, temp, target的初值分别为'A', 'B', 'C'。
递归的终点是:把1个盘从源柱移动到目标柱上。

void hanio(int n, char source, char temp, char target)
{
    if(n == 1)//递归的终点 
    move(source, target);
    else{
        //下面的代码是对文章开头步骤的复述
        hanio(n-1, source, target, temp);
        move(source, target);
        hanio(n-1, temp, source, target);
    }
}

 

完整代码如下:

#include <stdio.h>
void hanio(int n, char source, char temp, char target);
void move(char x, char y);

int main()
{
    int num = 3;
    hanio(num, 'A', 'B', 'C');
    return 0;
}
void hanio(int n, char source, char temp, char target)
{
    if(n == 1)//递归的终点 
        move(source, target);
    else{
    //下面的代码是对文章开头步骤的复述
        hanio(n-1, source, target, temp);
        move(source, target);
        hanio(n-1, temp, source, target);
    }
}

void move(char x, char y)
{
    printf("%c--->%c\n", x, y);
} 

不建议继续作微观思考,显然模型已经构造完毕。如果非要深入演绎,此处可以举个例子。
从上往下看,先看第一个任务:把n-1个盘从源柱移动到临时柱上。
这个任务重新表述为:把n-1个盘从源柱A移动到临时柱B上。
由于要达成把n-1个盘从源柱移动到临时柱B上这个目标,原问题中的临时柱B显然已经成为了本任务中的目标柱,而C柱本来在原问题中是目标柱,现在在这个任务中也就成了临时柱,源柱是A柱。
这里B和C发生了交换。A--源柱,B--目标柱,C--临时柱。

为了完成第一个任务,先要完成第二个任务:把n-2个盘从源柱移动到临时柱上。

我们来看第二个任务。
这个任务重新表述为:把n-2个盘从源柱A移动到临时柱C上。
在这个任务中,C柱俨然是目标柱,而B柱只好是临时柱了。
A--源柱,B---临时柱,C-目标柱。
这里,B和C又发生了交换,角色换回来了,和原问题的各柱扮演的角色一样,这样不断交换下去。
不信看第三个任务:把n-3个盘从源柱移动到临时柱上。
这个任务重新表述为:把n-2个盘从源柱A移动到临时柱B上。
那么B又成了目标柱。。。

posted @ 2018-09-29 08:19  谷谷非鼠  阅读(653)  评论(0编辑  收藏  举报