编程语言
首页 > 编程语言> > 递归算法以及Hanoi(汉诺)塔问题及其详细解释

递归算法以及Hanoi(汉诺)塔问题及其详细解释

作者:互联网

递归在算法中是非常重要的,可以说几乎所有的循环算法都可以用递归来实现,这足以体现递归的重要性,利用递归的条件一般为一下:

  1. 定义是递归的

像有些数学函数就是递归定义的,例如大家熟悉的阶层函数;

    2.利用“分治法”

在数据结构中有些数据结构是递归的,这又怎么理解呢?

如, 对于链表,其结点 LNode 的定义由数据域 data 和指针域 next 组成, 而指针域 next 是一种
指向 LNode 类型的指针, 即 LNode 的定义中又用到了其自身, 所以链表是一种递归的数据结构。
对于递归的数据结构, 相应算法采用递归的方法来实现特别方便。链表的创建和链表结点的 .
遍历输出都可以采用递归的方法。算法 3.9 是从前向后遍历输出链表结点的递归算法, 调用此递
归函数前,参数 p 指向单链表的首元结点,在递归过程中,p 不断指向后继结点,直到 p 为 NULL
时递归结束。显然, 这个问题满足上述给出的采用 “分治法” 进行递归求解的问题需要满足的三
个条件

代码如下:

void TraverseList(LinkList p)
{
if(p==NULL) return;//递归终止
else
{
cout<<p->data<<end;
TraverseList(p->next);
}
}

本次主要讲一下hanoi塔算法

问题规则:Hanoi(汉诺)塔问题。古代有一个焚塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在上,小的在下,有一个老和尚想把这64个盘子从A座移到C座,但规定每次只允许移到一个盘,且在移动过程中在3个座上都始终保持大盘在下,小盘在上,在移动过程中可以利用B座。输出移动盘子的步骤。

这里就拿四个盘来讲述:

我自己画了下详细步骤如下:

 

大家也可以动手画一画,没找到规律前并不是那么好画的!

对于这个问题的算法介绍:

设A柱上最初的盘子
总数为n, 则当n =l时,只要将编号为1的圆盘从塔座A直接移至塔座C上即可;否则,执行以下
三步:
(1) 用 C 柱做过渡,将 A 柱上的(n-l)个盘子移到 B 柱上;
(2) 将 A 柱上最后一个盘子直接移到 C 柱上;
(3) 用 A 柱做过渡,将 B 柱上的(n-l)个盘子移到C柱上。
根据这种解法,如何将 n -1个圆盘从一个塔座移至另一个塔座的问题是一个和原问题具有
相同特征属性的问题,只是问题的规模小1, 因此可以用同样的方法求解。

代码如下:

#include <stdio.h>
int m=0;
void Move(int n,char A,char B,char C)
{
        m++;
        //设置移动盘子的结束条件,如果A当前还有一个盘子那么就把他直接移动到C
        if(n == 1) {
                printf("%c -> %c\n",A,C);
        }else{
        //否则开始递归
                Move(n-1,A,C,B);//递归, 将A上编号为1至n-l的圆盘移到B, C做辅助塔;
                //直接将编号为n的圆盘从A移到C;
                printf("%c -> %c\n",A,C);

                Move(n-1,B,A,C);//递归, 将B上编号为1至n-1的圆盘移到C, A做辅助塔
        }
}

int main()
{
        int n;
        printf("请输入盘子数:");
        scanf("%d",&n);
        //如果有五个盘子,和A,B,C三个柱子,否则开始递归.
        Move(n,'A','B','C');
        printf("移动次数:%d次",m);
}

运行结果这里我输入的盘子数是4

以下是我在网上找到的详细移动步骤对了一下,代码是正确的

 

对于其算法的理解还是必须要深入理解才能写出代码来!!还是有点难的。

 

 

 

背影Tian 发布了16 篇原创文章 · 获赞 8 · 访问量 3045 私信 关注

标签:链表,汉诺,递归,Hanoi,问题,算法,盘子,柱上
来源: https://blog.csdn.net/LTtiandd/article/details/104199368