汉诺塔问题 最简单的图文讲解递归实现

问题简化:

假设有 A,B,C三个柱子。有n个盘子,从大到小依次放在A柱上,我们目标是把A柱的盘子移到C柱。遵循如下原则:

1.小盘的上面不能放大圆盘。

2.在三根柱子之间一回只能移动一个圆盘。

3.只能移动在最顶端的圆盘。 

解法介绍

在理解递归时,难点就像小学生理解方程一样,无法理解将未知的设置为x,假设它为已知的方式求解。递归也一样,我们将某个函数通过定义,假设它能实现这个功能,并且在函数内部又肯定会依赖于这个功能,会发生自己调用自己的情况。比如我们这里的功能机为:

tower(int n, string from, string to, string tmp)
这个功能机能实现将n个盘子,从源柱from,利用临时柱tmp,最终将盘子移动到目标柱to上。
它既然能将n个盘子搬过去,那一定也能将n-1个盘子搬过去。这就是递归的精髓。递归的出口就是当只有一个时,直接搬过去就行。

思路与源码:

这三个柱子在变换着充当源柱目标柱临时柱

1)如果只有一个盘子时,直接从源柱目标柱(对应代码标记A部分)

2) 否则就把所有上面的n-1个盘子,先从源柱移到临时柱(B部分)。再把第n个从源柱目标柱(C部分)。最后把n-1个盘子从临时柱目标柱(D部分)。这里和移动两个盘子的思路是一样的。

void tower(int n, string from, string to, string tmp) {
    if (n == 1) {
        cout << n  << from << " to " << to << endl;   //A
    }
    else {
        tower(n - 1, from, tmp, to);  //B
        cout << n  << from << " to " << to << endl; //C
        tower(n - 1, tmp, to, from); //D
    }
}

int main(int argc, char** argv) {
    tower(7, " A ", " C ", " B ");
}

 

posted @ 2021-01-05 10:19  Bigben  阅读(576)  评论(0编辑  收藏  举报