算法学习笔记(二)------递归之汉诺塔

本文详细解析了汉诺塔问题及其递归解决方案,介绍了递归的基本概念及应用,并通过具体实例展示了汉诺塔问题的递归求解过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很惭愧,本来打算把八皇后一口气也整理出来,但是看鬼畜耽误了学习时间一会还要背单词,今天就简单整理一下汉诺塔问题。

一个函数调用自己就是递归,递归和普通函数调用一样是通过栈实现的。
现实生活中的例子就是“我三分钟就到,如果没到,请再读一遍这个短信”。

如求n!

int Factorial(int n)
{
if(n == 0)  return 1;
else return n*Factorial(n-1);
}

阶乘调用栈

递归主要用处有三类。
①替代多重循环
②解决以递归形式定义的问题
③将问题分解为规模更小的子问题进行求解

汉诺塔问题,就是一种典型的递归问题。
汉诺塔是根据一个传说形成的一个问题:有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。问:如何移?最少要移动多少次?

其实通过汉诺塔问题的计算,我们不难发现,汉诺塔和数学归纳法有异曲同工之妙。

第一数学归纳法

一般地,证明一个与自然数n有关的命题P(n),有如下步骤:

(1)证明当n取第一个值n0时命题成立。n0对于一般数列取值为0或1,但也有特殊情况;

(2)假设当n=k(k≥n0,k为自然数)时命题成立,证明当n=k+1时命题也成立。

综合(1)(2),对一切自然数n(≥n0),命题P(n)都成立。

上个月听宇哥的课时候,宇哥还讲了一下(笑

**对于n > 1的时候,又可以得出这3步:
1)将底盘n以上的环(n-1个)移动到B
2)将底盘n从A移动到C
3)将B上的环(n-1个)移动到C**

在把n个盘子从A移动到C的过程中,必然存在一步,那就是把最大的盘子从A拿出来。

要想把最大的盘子从A移动到C上,就必须保证剩下的n-1个盘子不能碍事,得好好堆在剩下B杆上。要保证n-1个盘子都在B杆上,至少得付出F(n-1)次移动。

在把n个盘子从A移动到C的过程中,必然存在一步,那就是最大的盘子被放到了C上,而且此后再也没动过。

在这步实施之后,我们只要花至少F(n-1)的步数把n-1个盘子从BC上就行了。这些步数必然和1)中的步数不重叠,因为这时候最大盘子在C上,而1)中最大盘子在A上。

所以就是1+F(n-1)+F(n-1)次。

#include<iostream>
using namespace std;
void Hanoi(int n,char src,char mid,char dest)
//将src座上的n个盘子 以mid为中转,移动到dest座
{
    if( n == 1){
        cout << src <<"->"<<dest<<endl;
        return; 
    }
    Hanoi(n-1,src,dest,mid);
    //将n-1个盘子从src移动到mid所需要的步骤
    cout << src <<"->"<<dest<<endl;
    // 将最后一个移动到dest
    Hanoi(n-1,mid,src,dest);
    //将n-1个盘子从mid移动到dest所需要的步骤 
    return ;
} 
int main()
{
    int n;
    cin >>n;
    Hanoi(n,'A','B','C');
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值