汉诺塔(递归描述)

什么是汉诺塔
是根据一个传说形成的数学问题:

有三根杆子A,B,C。A杆上有 N 个 (N>1) 穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆:

  1. 每次只能移动一个圆盘;
  2. 大盘不能叠在小盘上面。

提示:可将圆盘临时置于 B 杆,也可将从 A 杆移出的圆盘重新移回 A 杆,但都必须遵循上述两条规则。
三个圆盘时的解法
汉诺塔
四个圆盘时的解法
汉诺塔
那么五个圆盘时的解法呢
现在我们规定 左边柱子编号为A,中间柱子编号为B,右边编号为C
A是初始位置,C是目标位置
那么5个圆盘的解法就是将上面四个圆盘移动到B 再将第5个圆盘移动到C
再将那四个圆盘从B移动到C就完成了

N个圆盘的解法
简单来说就是三步

  1. 将n-1个圆盘从A移至B
  2. 将第n个圆盘移至C
  3. 再将n-1个圆盘从B移至C

递归概念的引出
现在我们提出一个简单的汉诺塔问题:
给定N个圆盘的汉诺塔 求解需要移动多少次才能从初始状态抵达目标状态?
定义一个函数K K(N)表示N个圆盘的汉诺塔的移动次数
根据之前的思考 我们可以得到这样一个式子
K(N)=K(N-1)+1+K(N-1)=2*K(N-1)+1
那么求解K(N)即求解K(N-1)
而我们并不知道K(N-1)
但我们知道K(1)=1
那么我们如何将K(N),K(N-1)和K(1)联系起来
没错就是上面那个公式

其实我们可以直接通过上面的公式得知K(N)=2^N-1

这其实就是一个递归表达式
递归表达有着下面几个特点:

  1. 原本问题会在处理后,问题规模会变小(K(N)经过处理后变成K(N-1))
  2. 有边界(不能再小的问题,K(1)不用再变小)
int solve(int Size)//在这个问题中 B和C是不用区别的
{
	if(Size==1)
		return 1;
	return 2*solve(Size-1)+1;
}

递归的基本模式

  1. 我们已经完成了吗?如果完成了,返回结果。如果没有这样的终止条件,递归将会永远地继续下去。
  2. 如果没有,则简化问题,解决较容易的问题,并将结果组装成原始问题的解决办法。然后返回该解决办法。

汉诺塔问题(正常版本)
将移动过程按照
N from A to C(N表示盘子的编号,A,C表示柱子的编号)
的格式输出

void hannoi (int n, char from, char buffer, char to)
{
    if (n == 0)
        return;
    hannoi (n - 1, from, to, buffer);
    cout << "Move disk " << n << " from " << from << " to " << to << endl;
    hannoi (n - 1, buffer, from, to);
}

int main()
{
    int n;
    cin >> n;
    hannoi (n, 'A', 'B', 'C');
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值