汉诺塔问题想必大多数人都不陌生,它是递归思想的一个经典例子,这里只是简述一下:
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上安大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
这里回顾一下递归思想的概念,即将一个复杂问题分解成一系列小的问题,并且这些小问题都具有相同的情形。此时可运用递归的思想来解决更易于理解(但并不一定是效率最高的哦);
递归算法有两个关键点:1) 有明确的终止条件(通常是分解出来的一系列小问题里最简单的那种情况); 2) 随着递归算法的演进,数据规模在递减;
另外注意的一点是递归与循环之间的关系,一般来说,用循环能解决的问题用递归也能解决,但能用递归的问题不一定能用循环解决;
下面看汉诺塔问题的C语言实现代码:
代码文件: hanoi.c
/*************************************************************************
* Project:
* Function: 汉诺塔问题演示代码
*************************************************************************
* : magc $
* : magc@gmail.com $
*************************************************************************
*
* Copyright 2011 by magc
*
************************************************************************/
#include "hanoi.h"
/***********************************************************
参数n :共n个盘子
参数A : 源柱子
参数B :要借助的柱子
参数C :要移到的目标柱子
注:这里的A,B,C三个柱子是逻辑上的源,中间介质,目标柱子,并不固定是左/中/右三个柱子。
***********************************************************/
void hanoi(int n , char A , char B , char C)
{
if(1 == n) //最简单的情况,终止递归的条件
{
printf("移动%c柱上第1个到%c\n",A , C);
}else
{
hanoi(n-1 , A , C , B); //先将源柱子上的n-1个盘子移到中间介质上
printf("移动%c柱上第%d个到%c\n",A , n , C); //然后将源柱子上的第n个移到目标柱上
hanoi(n-1 , B , A , C); //下面再将中间柱子上的n-1个盘子作为一个新的汉诺塔问题解决
}
}
代码文件: hanoi.h
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void hanoi(int n , char A , char B , char C);
代码文件 : main.c
#include <stdio.h>
#include <stdlib.h>
#include "hanoi.h"
int main()
{
int num = 0;
printf("请输入总个数:\n");
scanf("%d",&num);
hanoi(num , 'A','B','C');
return 0;
}
编译运行后,2个盘子时,输出如下:
3个盘子时,输出如下:
4个盘子时,输出如下:
另外可以发现操作步骤与总个数有关系,2个时需要操作2的2次方,3个时需要2的3次方,4个时需要2的4次方,由此可推测出传说中的那64个盘子时,总共要移动2的64次方,这对于人工操作来说的确算得上是天文数字了,不信大家拿你的机器试试,呵呵,小心别死机哦,