说明:
河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。
分析:
假设三根石柱分别为A,B,C,目标是将A石柱上的64个金盘移到C石柱上。可以这样分析,如果A石柱只有一个盘子,则直接A -> C(由A移到C)。如果A石柱有两个盘子,则现需要这样移动:A -> B , A -> C ,B -> C。那如果是三个盘子呢?这时就很难想象出该如何移动了。但是三个盘子的移动可以分解成三个大步骤:
(1)将前两个盘子由A -> B(将C作为辅助);
(2)在将A中最后的一个盘子直接由A -> C,此时A石柱就空了,B石柱放置了两个金盘,C石柱放置了一个最大的金盘;
(3)最后只需要借助空柱子A,将B石柱的两个盘子由 B -> C(将A作为辅助)。
这样分析,就可以发现河内之塔是个递归问题。将n个盘子由A -> C(借助B)可以分解为三个步骤: 将前n-1个盘子由A -> B(借助C),将第n个盘子直接由 A -> C,将B石柱的n-1个盘子由B -> C(借助A)。
实现:
/**************************************************************** Name: HanoiTowers.c Description: the problem is a classical recursion problem Author: fuchencong@163.com Time: 2014-9-10 ****************************************************************/ #include <stdio.h> void MoveTowers(int n,char begin,char middle,char end) { if(1==n) { printf("%c -> %c\n",begin,end); return; } MoveTowers(n-1,begin,end,middle); printf("%c -> %c\n",begin,end); MoveTowers(n-1,middle,begin,end); } int main() { int nDisks; printf("please input the disks:\n"); scanf("%d",&nDisks); MoveTowers(nDisks,'A','B','C'); return 0; }
河内之塔是个典型的递归求解问题,只要认真分析,就能发现这个问题存在子结构。
原文地址:http://blog.csdn.net/fuchencong/article/details/39213565