汉诺塔递归问题(C语言)

汉诺塔递归问题(C语言)

  • 问题由来
  • 问题分解
  • 原代码
  • 运行结果
  • 重要步骤
  • 感悟

问题由来

汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。————百度百科

汉诺塔问题可能有的人知道,有的人不知道,今天小科就来讲解一下

汉诺塔问题是一道比较复杂的递归问题,但是想到递归的两个必要条件

  • 每次递归调用之后越来越接近这个限制条件

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续。

问题分解

我们将问题转换为:

假设有n个圆盘,我们的目标是:将N个圆盘从第一个柱子移到第三个柱子。那么可以把问题分解为:
1.将n-1个圆盘从第一个柱子移到第二个柱子
2.将第n个圆盘从第一个柱子移到第三个柱子
3.将n-1个圆盘从第二个柱子移到第三个柱子

图解:
汉诺塔递归问题(C语言)_第1张图片
那么我们来分析一下:

n=3时,步骤:
A->C
A->B
C->B
A->C
B->A
B->C
A->C

原代码

那我们来写下代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include

void move(char X,char Y)
{
     
	printf("%c->%c",X,Y);
}
void hanoi(int n, char a, char b, char c)//表示n个盘子,a,b,c三根柱子
{
     
	if (n == 1)
	{
     
		move(a, c);
	}
	else
	{
     
		hanoi(n-1,a,c,b);//表示a柱上的n-1个盘子借助c柱移向b柱
		move(a,c);//表示a柱上第n个盘子移向c柱
		hanoi(n-1,b,a,c);//表示b柱上的n-1个盘子借助a柱移向c柱
	}
}
main()
{
     
	int n=0;
	printf("请输入盘子的数量:");
	scanf("%d",&n);
	printf("盘子移动的过程:");
	hanoi(n,'A','B','C');//调用函数递归求盘子移动轨迹
	
	return 0;
}

运行结果

3
A->C
A->B
C->B
A->C
B->A
B->C
A->C

D:\c code\小题库\汉诺塔问题\Debug\汉诺塔问题.exe (进程 13928)已退出,代码为 0。
按任意键关闭此窗口. . .

重要步骤

		hanoi(n-1,a,c,b);//表示a柱上的n-1个盘子借助c柱移向b柱
		move(a,c);//表示a柱上第n个盘子移向c柱
		hanoi(n-1,b,a,c);//表示b柱上的n-1个盘子借助a柱移向c柱

你会发现n个盘子所需的步数为2的n次方减一,并且为什么是a,c,b;b,c,a这两个步骤?

这是因为第一步永远从a柱拿出盘子,最后一步永远是把盘子放到c柱
但是如果都是a,b,c这样的顺序,将不会有任何意义
同时 hanoi函数的形参对应的值会影响move函数的打印

这个问题不好描述,所以换成浅显易懂的语言

感悟

其实我自己也看了不少文章,经过仔细推敲才搞懂这个顺序
所以大家可以自己仔细推敲细节,争取弄得透彻

如果有错误,希望各位看我文章的小伙伴提出来

各位的支持是我创作的全部动力,拜拜

你可能感兴趣的:(汉诺塔递归,算法,c语言)