hanoi塔问题的详解(分治思想+递归)

        汉诺塔问题一直是研究递归算法的一个经典案例,也被很多教材当成递归算法的进阶案列,今天,我们就来看一下这个汉诺塔问题!

首先明白什么叫汉诺塔问题:

首先有三个柱子:分别是

起始柱子(最左边): source
辅助柱子(最右边): helper
目标柱子(中间): dest 

柱子上有诺干个盘子,我们通过移动让左右的盘子从小到大的堆放在目标柱子上(中间柱子)

 下面是移动的动作

 然后我们需要做的就是,写一个算法,把每次移动的动作放在一个数组里面,让算法计算怎么移动能达成目标,先看一下结果

 看着这个

      数组,是不是就能很清晰的看到是怎么走的了?哪怕有100个盘子,也能很快的计算出怎么走,只要根据数组上面的步骤执行就可以了 

清楚了我们的目标,接下来一块写代码吧

 我先把代码展示出来,然后再说明一下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    /** 
 * @param {圆盘数:number} plates 
 * @param {起始柱子 a:string} source 
 * @param {辅助柱子 b:string} helper 
 * @param {目标柱子 c:string} dest 
 * @param {移动步骤集:Array,数组的长度就是移动的次数} moves 
 */
    var move1 = []
    function hanoi(plates, source, helper, dest, moves = []) {
        if (plates <= 0) {
            return moves;
        }
        if (plates === 1) {
            moves.push([source, dest]);
            move1.push([source, dest, helper]);
        } else {
            hanoi(plates - 1, source, dest, helper, moves);
            moves.push([source, dest]);
            hanoi(plates - 1, helper, source, dest, moves);
        }
        return moves;
    }

    // test
    console.log(hanoi(5, 'source', 'helper', 'dest')); // 输出结果如下图展示
</script>
</html>

 最难的是else里面的两次递归调用,这个不太好讲,我做了个图,帮助理解!

 

5层的汉诺塔太大了,不太好截图,我放个4层的,其实原理是一样的, 

4层就是2的四次方-1,也就是15次;

5层就是2的5次方-1,得到31次;


这个不太好理解,也得花时间,我当时搞了一晚上,才画出的图,有兴趣的小伙伴可以私我,大家一块讨论,如果有不正确的地方,欢迎大家伙指导!

猜你喜欢

转载自blog.csdn.net/fightingLKP/article/details/126254841