递归 汉诺塔

汉诺塔

内涵数据结构为: 栈(先进后出) 算法思想: 递归(调用函数自身)

汉诺塔 (输出移动过程:展示递归)

题目:
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。

请编写程序,表示将所有盘子从第一根柱子移到最后一根柱子的过程。

img

思路:

分两种情况

其一:
当需要移动的盘子只有一个 ,则直接将其移动到目的柱子( C )

其二:
当需要移动的盘子大于一,则先将其除最底层外的盘子移动到辅助柱子(B)
再将最底层的盘子移动至目的柱子 ( C )
现在可将移动至辅助柱子(B)的盘子视为一个新的汉诺塔(层数为n-1)
重复以上操作即可(即 :调方法本身 )
其移动的目的柱子不变(还是C)
辅助柱子(变更为A)

代码:

#include<iostream>
using namespace std;
void move(int n, char A, char B, char C)
{
	//若为层数为一 将其直接移动到目的容器C
	if (n == 1)
		cout << n << ":  " << A << "--->" << C << endl;
	//若层数大于一  
	else
	{
		//将其分成两部分
		//一部分为 上(n-1)层  要先将其移动到辅助容器B
		move(n - 1, A, C, B);
		//再将第二部分 第n层  移动到目的容器C中
		cout << n << ":  " << A << "--->" << C << endl;
		//处理产生的新的 汉诺塔(n-1) 调用函数本身
         //其实容器和辅助容器 相对改变 目的容器不变
		move(n - 1, B, A, C);
	}
}
int main()
{
	//汉诺塔层数 
	int n;
	cout << "输入汉诺塔层数:";
	cin >> n;
	// A	B	C 表示三个容器
	char A = 'A', B = 'B', C = 'C';
	move(n, A, B, C);
	return 0;
}

结果为每层盘子的移动过程:
在这里插入图片描述

这个程序输出过程用于方便理解…


汉诺塔(内涵数据结构:栈)

实际上,汉诺塔中隐藏了一个数据结构–栈

汉诺塔的每个柱子都是只能移动最上层的盘子

每个盘子(元素)进入柱子(入栈)离开柱子(出栈)时,都遵行 :先进后出的原则

将上述算法,和栈相结合:

代码:

#include<iostream>
#include <stack>
using namespace std;
void movezhan(int n, stack<int> &A, stack<int> &B, stack<int> &C)
{
	//若为层数为一 将其直接入栈至目的栈C
	if (n == 1)
	{
		C.push(A.top());
		A.pop();
	}
	//若层数大于一  
	else
	{
		//将其分成两部分
		//一部分为 上(n-1)层  要先将其移动到辅助栈B
		movezhan(n - 1, A, C, B);
		//再将第二部分 第n层  移动到目的栈C中
		C.push(A.top());
		A.pop();
		//处理产生的新的 汉诺塔(n-1) 调用函数本身
		//其初始栈A和辅助栈B 相对改变 目的栈C不变
		movezhan(n - 1, B, A, C);
	}
}
int main()
{
	stack<int> A, B, C;
	int n;
	cout << "输入栈的层数(元素从1线性增加至n):";
	cin >> n;
	//初始化 栈A
	for (int i = n; i > 0; --i)
	{
		A.push(i);
	}
	movezhan(n, A, B, C);
	return 0;
}

结果展示:

在这里插入图片描述
由栈A中的五个元素
在这里插入图片描述
转移至至栈C中的五个元素
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值