C语言递归实现n阶汉诺塔操作过程

汉诺塔(Tower of Hanoi)是一个源于印度古老传说的益智玩具。基本规则很简单,有三个立柱,然后在最左边放着n个盘子叠成的“塔”,要求把所有盘子移到最右边的柱子,一次只能移动一个盘子,并且不能从中间抽出盘子,即只能拿最上面的盘子,并且移动盘子过程中需始终遵循大盘子在小盘子下面的原则。
程序要求:已知三根柱子从左到右依次标号A、B、C。输入一个正整数n,表示最左边的柱子一开始盘子的个数,盘子初始状态也遵循大盘子在小盘子下面的原则,并且盘子从小到大依次标号为1、2、…、n。要求打印出每次对盘子的操作,并且每次操作单独占一行,比如:把柱子A最上面的标号为i的盘子移动到柱子B上,即打印“Move plate i from A to B.",操作结束后,要求打印操作的次数。
思路:
本文用递归实现操作过程,因此要思考递归实现问题的基本思路:大问题化小问题。递归是一种经典的分治算法思想,将大问题化为若干小问题解决。因此我们想到,如果要把A柱的n层塔移动到C柱,必须要把编号为n的盘子从A移动到C,而要移动编号为n的盘子,必须把标号为1到n-1的盘子移开,不然n号盘我们动不了,而且1号到n-1号盘子都必须在B柱,因为我们的n号盘要放在C柱的最底下,又因为盘子的叠放要遵循大盘子始终在小盘子下面的原则,因此这n-1个盘子均叠放在B柱并且是从小到大叠放的,即我们把一个n-1阶的汉诺塔从A柱移动到了B柱。
C语言递归实现n阶汉诺塔操作过程_第1张图片

看到这里可能有些读者已经明白了这个算法的实现过程。我们把三根柱子分成出发柱、过程柱、目的柱。比如我们的初始问题,把n阶汉诺塔从A柱移动到C柱,那么A柱就是出发柱,C柱就是目的柱,B柱就是我们的过程柱,我们要借助这个过程柱实现我们的搬运过程。我们要实现n阶汉诺塔的移动,就得先把n-1阶的汉诺塔从A柱移动到B柱,然后把第n号盘从A柱移动到C柱,再把n-1阶的汉诺塔移动到C柱。
C语言递归实现n阶汉诺塔操作过程_第2张图片
C语言递归实现n阶汉诺塔操作过程_第3张图片
而对于n-1阶汉诺塔从A到B的移动,出发柱还是A,但是目的柱变成了B,过程柱变成了C,即利用C把盘堆从A移动到B,后来把n-1阶汉诺塔从B到C的移动,出发柱成了B,目的柱变成了C,过程柱变成了A。而n-1阶汉诺塔的移动又变成了n阶汉诺塔的移动,只是这个n变成了n-1。所以我们在编程中要给递归函数出发柱、过程柱、目的柱描述此时的过程。因此思路是这样,下面上代码:

#include
int cont=0;//用来记录操作次数,此处使用全局变量
void Hanoi(int n,char start,char end,char process)//此处标识符的使用是为了便于读者理解,实际使用时可以适当简化
{
     
    cont++;
    if(n==1)//只剩最后一个盘子(即1号盘)时,直接移动即可
    {
     
        printf("Move plate 1 from %c to %c.\n",start,end);
        return;
    }
    else
    {
     //此大括号内的目的、过程、出发都是对本次函数体内的移动过程而言,即对此时n个盘子的移动过程而言
        Hanoi(n-1,start,process,end);//将n-1阶汉诺塔从出发柱移动到过程柱,通过目的柱
        printf("Move plate %d from %c to %c\n",n,start,end);//将最下面的大盘子从出发柱直接移动到目的柱
        Hanoi(n-1,process,end,start);//将n-1阶汉诺塔从过程柱移动到目的柱,通过出发柱
    }
}
int main(){
     
    char a='A',b='B',c='C';
    int n;
    printf("Now tell me how much plates you want to move?\n")
    scanf("%d",&n);
    Hanoi(n,a,c,b);//把n个盘子从A柱移动到C柱,借助B柱
    printf("There are %d moves in total.\n",cont);
    return 0;
}

你可能感兴趣的:(C语言,算法,c++,递归算法)