汉诺塔(递归)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kwansy/article/details/78628940

阅读递归函数最容易的方法不是纠缠于它的执行过程,而是相信递归函数会顺利完成它的任务。如果你的每个步骤正确无误,你的限制条件设置正确,并且每次调用之后更接近限制条件,递归函数总是能够正确地完成任务。——《C和指针》

一、游戏规则

有三个塔,第一个塔上放了若干个盘子。要将这若干个盘子借助第二个塔移动到第三个塔上面。规则只有一个,大盘子必须在小盘子上面。

这里写图片描述


二、伪算法

定义一个函数,接收4个参数,分别是:盘子的个数、起始柱子、辅助柱子、目标柱子。

函数原型

void hanoi(int n, int src, int temp, int dst);

我们的hanoi函数将一件事分解成三件小事,而这三件小事本质上和它本身做的工作是一样的。将 n 个盘子移动到另一根柱子,和将 n-1 个盘子移动到另一根柱子,没有任何区别。当n=1时,可以直接移动。

伪算法

如果只有一个盘子
    直接移动到目标柱子
否则  
    将 n-1 个盘子移动到辅助柱子
    将最后一个盘子移动到目标柱子
    将 n-1 个盘子从辅助柱子移动到目标柱子

没了,就这么简单。根本不需要管 n-1 个盘子是怎么移动的,也不需要担心大盘子会跑到小盘子上面,递归函数帮我们做好了一切。


三、代码实现

#include <stdio.h>

// 第一个参数是盘子数、第二个参数是起始柱子、然后是辅助柱子、最后一个是目标柱子
void hanoi(int n, int src, int temp, int dst);

int main() {
    // 借助第二根柱子,将3个盘子从第一根柱子移动到第三根柱子
    hanoi(3, 1, 2, 3);

    return 0;
}

void hanoi(int n, int src, int temp, int dst) {
    if (n == 1) {
        printf("%d -> %d\n", src, dst);
    }
    else {
        // 请仔细观察参数的顺序
        hanoi(n - 1, src, dst, temp);
        hanoi(1, src, temp, dst);
        hanoi(n - 1, temp, src, dst);
    }
}

这里写图片描述


四、总结

递归的两个要素:一个是必须要有出口;另一个就是通过调用自己来简化问题,使每次递归后都更接近出口。

不要尝试跟踪递归的每一步,这样只会让问题变得复杂。

扫描二维码关注公众号,回复: 3617704 查看本文章

猜你喜欢

转载自blog.csdn.net/Kwansy/article/details/78628940