【递归问题】——汉诺塔

简介: 【递归问题】——汉诺塔

问题背景

汉诺塔问题是由法国数学家卢卡斯于1883年提出的。他还为此赋予了一个罗曼蒂克的传说:


在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

解题分析

       解决该问题的最好的方法就是对它进行稍加推广,汉诺塔有64个圆盘,8个圆盘,我们可以将问题推广到有n个圆盘,这就是递归的思想,先研究小的情况。


       只有一个或两个圆盘时是很容易求解的,现在将问题推广到三个圆盘,先将上面两个圆盘移动到中间的桩柱上,再移动第三块圆盘,接着再把其余两个放到它上面。现在我们再将问题推广到n个圆盘。


问题归纳

首先把n-1个小的圆盘移动到一个不同的桩柱上(需要T~n-1~次移动),然后移动最大的圆盘(需要一次移动),最后再把那n-1个小圆盘移到最大的圆盘上(这需要另外的T~n-1~次移动)


这样就需要2T~n-1~  +  1次移动就能移动n个圆盘了。

现在我们就可以根据得到的递归式连续计算T3=2*3+1=7,T4=2*7+1=15……

然后就根据上续计算结果用数学归纳法得到T~n~=2^n - 1

现在我们就已经把问题分析透彻了,只需要转化为代码就可以了


代码实现

现在设有N个盘子从X杆经由Y杆移动到Z杆


hanoi (N - 1, X , Y , Z );把n-1只碟子从X杆经Z杆移动到Y杆

move(X , Z);将X杆上第n只碟子移动到Z杆

hanoi (N - 1, Y , X , Z );然后再将n-1只碟子从Y杆经X杆移到Z杆

#include <stdio.h>
void hanoi(int, char, char, char);
void move(char, char);
int main()
{
  int n = 0;
  printf("Please input n:");
  scanf("%d", &n);
  hanoi(n, 'a', 'b', 'c');
  return 0;
}
//有n个圆盘,从x移到z,用y作临时存放
void hanoi(int n, char x, char y, char z)
{
  if (n == 1)
    move(x, z);
  else
  {
    hanoi(n - 1, x, z, y);
    move(x, z);
    hanoi(n - 1, y, x, z);
  }
}
//显示圆盘的移动
void move(char c1, char c2)
{
  printf("%c -> %c\n", c1, c2);
}
相关文章
|
8月前
|
算法 C语言
汉诺塔问题(函数递归)
汉诺塔问题(函数递归)
91 0
|
9月前
|
Java Python
汉诺塔递归问题,递归思路详解
汉诺塔递归问题,递归思路详解
136 0
|
9月前
|
机器学习/深度学习
利用函数递归求汉诺塔问题
利用函数递归求汉诺塔问题
68 0
汉诺塔 递归问题
汉诺塔 递归问题
91 0
递归问题的实际运用:汉诺塔问题
递归问题的实际运用:汉诺塔问题
129 0
递归问题的实际运用:汉诺塔问题
|
C++ C语言
你是真的“C”——函数递归详解汉诺塔
利用函数递归手把手求解汉诺塔
117 0
你是真的“C”——函数递归详解汉诺塔
|
C语言
【C】青蛙跳台阶和汉诺塔问题(递归)
【C】青蛙跳台阶和汉诺塔问题(递归)
138 0
【C】青蛙跳台阶和汉诺塔问题(递归)
汉诺塔(递归+ 非递归版)
汉诺塔问题(又称为河内塔问题),是一个大家熟知的问题。在A,B,C三根柱子上, 有n个不同大小的圆盘(假设半径分别为1-n吧),一开始他们都叠在我A上(如图所示),你的目标是在最少的合法移动步数内将所有盘子从A塔移动到C塔。 游戏中的每一步规则如下:
266 1
汉诺塔(递归+ 非递归版)