汉诺塔详解及C++实现

汉诺塔是典型的递归问题,这个问题可以这样描述:

完成目标:将n个block块从A搬运到C,求需要移动多少次完成?

约束条件:搬运的过程中每次只能移动一个block块,且不能出现大的block块在小的block块之上。

详细分析如下:

为了分析将A中的n个block搬到C中,我们先分析一下n分别等于1,2,3的简单情况,在进行搬运之前我们有如下约定:

1、move(n,A,B,C)表示将n个block从A借助B搬到C中

2、move(1,A,C,B)表示将1个block从A搬到B中

第一种情况: 

 n = 1,将A中的①直接移动到C   move(1,A,B,C)  (直接从一个柱移动到另一个柱)

第二种情况:

n = 2,分3步

第一步:将①从A移动到B  move(1,A,C,B) (直接从一个柱移动到另一个柱)

第二步:将②从A移动到C  move(1,A,B,C)  (直接从一个柱移动到另一个柱)

第三步:将①从B移动到C  move(1,B,A,C)   (直接从一个柱移动到另一个柱)

第三种情况:

n = 3,分三步

第一步:将①和②从A借助C搬到B  move(2,A,C,B)

第二步:将③从A搬到C  move(1,A,B,C)  (直接从一个柱移动到另一个柱)

第三步:将①和②从B借助A搬到C  move(2,B,A,C)

 

在这里我们进一步看一下第一步的move(2,A,C,B)和第三步的move(2,B,A,C)

1、将①和②从A借助C搬到B,move(2,A,C,B),其实又包含3个简单的步骤:

先将①从A搬到C,move(1,A,B,C);然后将②从A搬到B,move(1,A,C,B);最后将①从C搬到B,move(1,C,A,B)

2、将①和②从B借助A搬到C, move(B,A,C),其实也包含3个简单的步骤:

先将①从B搬到A,move(1,B,C,A);然后将②从B搬到C,move(1,B,A,C);最后将①从A搬到C,move(1,A,B,C)

好了,到这里就已经实现了n = 3的汉诺塔移动 是不是有点绕?其实自己在本子上画一下挺简单的,只是我把他写复杂了而已...

画了个图,假装看起来简洁点: 

可以看到最后的每一步操作都是到位的,也就是可以直接将block块从一个柱移动到另一个柱

第四中情况:

block为n的时候,分三步

第一步:将A中前n-1个block块借助C搬到B中  move(n-1,A,C,B)

第二步:将A中的第n个block块搬到C中  move(1,A,B,C)

第三步:将B中的n-1个block块借助A搬到C中  move(n-1,B,A,C)

那么第一步move(n-1,A,C,B)和第三步move(n-1,B,A,C)的实现又可以重复利用同样的思想,直到n-2,n-3,,,3,2,1就可以直接一步到位如move(1,A,B,C).

C++实现:

#include <iostream>
using namespace std;

void move(int n,char A,char B,char C);
int step;
int main()
{
    int n;
    cout<<"请输入block数n:"<<endl;
    cin>>n;
    move(n,'A','B','C');
    return 0;
}
void move(int n,char A,char B,char C)
{
    if(n==1)
    {
        step++;
        cout<<"["<<step<<"]move 1# from "<<A<<" to "<<C<<endl;
    }
    else
    {
        move(n-1,A,C,B);
        cout<<"["<<step<<"]move "<<n<<"# from "<<A<<" to "<<B<<endl;
        step++;
        move(n-1,B,A,C);
    }
    
}

参考连接:https://wenku.baidu.com/view/dba81a9ecf2f0066f5335a8102d276a2002960a1.html?from=search

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值