Hanoi塔问题
- 问题描述: 有3根杆(A,B,C),在A杆自下而上,由大到小按顺序放置n个盘、
- 目标:把A杆上的盘全部移动到C杆,并保持原有顺序
- 规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A,B,C任意杆上
问题分析(递归算法)n个盘子
n=1
A->C
n=2
P1–A->B
P2–A->C
P1–B->C
n=3
n=n时
非递归算法
代码实现–递归算法
#include <stdio.h>
void move(int n, char pos1, char pos3)
{
//打印移动的过程
// 1代表上面最小的盘子
// 2代表中间位置的盘子
// 3代表下面最大的盘子
printf("盘子%d: 从 %c柱 移动到 %c柱\n", n, pos1, pos3);
}
void Hanoi(int n, char pos1, char pos2, char pos3)
{
//如果是1个盘子,直接从起始柱A移动到目标柱C
if (n == 1)
{
move(n, pos1, pos3);
}
else
{
//如果盘子大于1个,需要把n-1个盘子,从起始柱pos1,通过目标柱pos3,移动到中转柱pos2
Hanoi(n-1, pos1, pos3, pos2);
//此时pos1上的n-1个盘子全部移动pos2上去了,那么可以直接把pos1上剩下的1个盘子,直接移动到pos3上
move(n, pos1, pos3);
//把pos2剩下的n-1个盘子,通过中转位置pos1,移动到目标位置pos3
Hanoi(n-1, pos2, pos1, pos3);
}
}
int main()
{
//盘子个数
int m;
printf("input the number of disks:");
scanf("%d",&m); //盘子的数量
//起始柱A
char pos1 = 'A';
//中转柱B
char pos2 = 'B';
//目标柱C
char pos3 = 'C';
printf("移动%d个盘子的步骤如下↓\n", n);
//汉诺塔函数
Hanoi(n, pos1, pos2, pos3);
return 0;
}
时间复杂度/移动步数–n 个盘子
时间复杂度=2^n-1
代码实现思路
起始柱-A
中转柱-B
目标柱-C
- n=1
盘子1:起始柱到目标柱A->C - n=2 起始柱:盘子2》盘子1,中转柱:0,目标柱:0
- step1:起始柱:盘子2,中转柱:盘子1,目标柱:0
盘子1:起始柱到中转柱A->B - step2:起始柱:0,中转柱:盘子1,目标柱:盘子2
盘子2:起始柱到目标柱A->C - step3:起始柱:0,中转柱:0,目标柱:盘子2》盘子1
盘子1:中转柱到目标柱B->C
- step1:起始柱:盘子2,中转柱:盘子1,目标柱:0
- n=3 起始柱:盘子3》盘子2》盘子1,中转柱:0,目标柱:0
- step1:起始柱:盘子3》盘子2,中转柱:0,目标柱:盘子1
盘子1:起始柱到目标柱A->C - step2:起始柱:盘子3,中转柱:盘子2,目标柱:盘子1
盘子2:起始柱到中转柱A->B - step3:起始柱:盘子3,中转柱:盘子2》盘子1,目标柱:0
盘子1:目标柱到中转柱C->B - step4:起始柱:0,中转柱:盘子2》盘子1,目标柱:盘子3
盘子3:起始柱到目标柱A->C - step5:起始柱:盘子1,中转柱:盘子2,目标柱:盘子3
盘子1:B->A - step6:起始柱:盘子1,中转柱:0,目标柱:盘子3》盘子2
盘子2:B->C - step7:起始柱:0,中转柱:0,目标柱:盘子3》盘子2》盘子1
盘子1:A->C
- step1:起始柱:盘子3》盘子2,中转柱:0,目标柱:盘子1
- n=4
移动4个盘子的步骤如下↓
盘子1: 从 A柱 移动到 B柱
盘子2: 从 A柱 移动到 C柱
盘子1: 从 B柱 移动到 C柱
盘子3: 从 A柱 移动到 B柱
盘子1: 从 C柱 移动到 A柱
盘子2: 从 C柱 移动到 B柱
盘子1: 从 A柱 移动到 B柱
盘子4: 从 A柱 移动到 C柱
盘子1: 从 B柱 移动到 C柱
盘子2: 从 B柱 移动到 A柱
盘子1: 从 C柱 移动到 A柱
盘子3: 从 B柱 移动到 C柱
盘子1: 从 A柱 移动到 B柱
盘子2: 从 A柱 移动到 C柱
盘子1: 从 B柱 移动到 C柱
n=4调试过程
n=4
传入Hanoi(n, pos1, pos2, pos3);
此时在Hanoi(n, pos1, pos2, pos3); (n=4)的执行框中:
n=4>1
n-1=3,交换pos2和pos3,传入子函数Hanoi(n - 1, pos1, pos3, pos2);
传入:
调用结果:
此时在Hanoi(n, pos1, pos2, pos3); (n=3)的执行框中:
n=3>1
n-1=2,交换pos2和pos3,传入子函数Hanoi(n - 1, pos1, pos3, pos2);
传入:
调用结果:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5e10cb37d26e7ca9ffe923a45f59fb1a.png
此时在Hanoi(n, pos1, pos2, pos3); (n=2)的执行框中:
n=2>1
n-1=1,交换pos2和pos3,传入子函数Hanoi(n - 1, pos1, pos3, pos2);
传入:
此时在Hanoi(n, pos1, pos2, pos3); (n=1)的执行框中:
此时n==1,传入pos1和pos3,调用子函数move(n, pos1, pos3);
传入:
printf(“盘子%d: 从 %c柱 移动到 %c柱\n”, n, pos1, pos3);
调用结果:
n–盘子
此时n-1=1,交换pos2和pos3,传入子函数Hanoi(n - 1, pos1, pos3, pos2); 的调用结束
也就是Hanoi(n, pos1, pos2, pos3); (n=1)的执行框执行完毕
执行结果:
此时回到n-1=2,交换pos2和pos3,传入子函数Hanoi(n - 1, pos1, pos3, pos2); 的执行框
也就是此时在Hanoi(n, pos1, pos2, pos3); (n=2)的执行框中:
此时在Hanoi(n, pos1, pos2, pos3); (n=2)的执行框中:
子函数Hanoi(n - 1, pos1, pos3, pos2);(n=1)的调用结束了
进入下一步:调用move(n, pos1, pos3);
传入:
调用结果:
进入下一步
此时在Hanoi(n, pos1, pos2, pos3); (n=2)的执行框中:
此时n=2
把n-1=1,pos1和pos2交换位置传入Hanoi(n - 1, pos2, pos1, pos3);
传入:
此时在Hanoi(n, pos1, pos2, pos3); (n=1)的执行框中:
此时n==1,传入pos1和pos3,调用子函数move(n, pos1, pos3);
传入:
调用结果:
此时此时n-1=1,交换pos2和pos3,传入子函数Hanoi(n - 1, pos1, pos3, pos2); 的调用结束
也就是Hanoi(n, pos1, pos2, pos3); (n=2)的执行框执行完毕
执行结果:
此时回到n-1=3,交换pos2和pos3,传入子函数Hanoi(n - 1, pos1, pos3, pos2); 的执行框
也就是此时在Hanoi(n, pos1, pos2, pos3); (n=3)的执行框中:
子函数Hanoi(n - 1, pos1, pos3, pos2);(n=1)的调用结束了
进入下一步:调用move(n, pos1, pos3);
传入:
调用结果:
进入下一步
此时在Hanoi(n, pos1, pos2, pos3); (n=3)的执行框中:
此时n=3
把n-1=2,pos1和pos2交换位置传入Hanoi(n - 1, pos2, pos1, pos3);
········
以此类推直到Hanoi(n, pos1, pos2, pos3); (n=4)的执行框执行完毕
以上就是对函数 Hanoi(int n, char pos1, char pos2, char pos3)递归过程的调试
最终执行结果: