汉诺塔问题的递归算法和非递归算法

文章详细介绍了汉诺塔问题,包括问题描述、递归算法分析、非递归算法、递归算法的C语言实现以及移动步数的时间复杂度。通过递归函数`Hanoi`的调用过程,展示了如何将n个盘子从起始柱移动到目标柱,同时保持大盘在下,小盘在上的规则。
摘要由CSDN通过智能技术生成

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
  • 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
  • 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)递归过程的调试

最终执行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值