資料結構與演算法題目集7-17——漢諾塔的非遞迴實現
阿新 • • 發佈:2018-12-05
我的資料結構與演算法題目集程式碼倉:https://github.com/617076674/Data-structure-and-algorithm-topic-set
原題連結:https://pintia.cn/problem-sets/15/problems/821
題目描述:
知識點:遞迴、棧
思路一:遞迴實現
遞迴終止條件:
當N為1時,直接將一個盤子從a移動到c即可。
遞迴過程:
(1)先將n - 1個盤子從a通過c移動到b。
(2)再將一個盤子從a移動到c。
(3)最後將n - 1個盤子從b通過a移動到c。
時間複雜度和空間複雜度均為O(2 ^ N)。
C++程式碼:
#include<iostream> int N; void hannoTower(int n, char a, char b, char c); //將n個盤子藉助b,從a移動到c int main(){ scanf("%d", &N); hannoTower(N, 'a', 'b', 'c'); return 0; } void hannoTower(int n, char a, char b, char c){ if(n == 1){ printf("%c -> %c\n", a, c); return; } hannoTower(n - 1, a, c, b); printf("%c -> %c\n", a, c); hannoTower(n - 1, b, a, c); }
C++解題報告:
思路二:非遞迴實現
非遞迴實現,就是利用我們自己的棧來代替系統棧,這個做法在LeetCode094——二叉樹的中序遍歷的思路二、LeetCode144——二叉樹的前序遍歷的思路二、LeetCode145——二叉樹的後序遍歷的思路二均有涉及。
就是將一條一條的指令壓入棧中,當然,需要額外一個一個bool型變數move表示當前命令需不需要移動盤子,輸出移動盤子的路徑。
注意,命令入棧順序和遞迴呼叫的順序是相反的。
時間複雜度和空間複雜度均為O(2 ^ N)。
C++程式碼:
#include<iostream> #include<stack> using namespace std; struct command { bool move; int n; char a, b, c; command(bool _move, int _n, char _a, char _b, char _c) { move = _move; n = _n; a = _a; b = _b; c = _c; } }; int N; int main() { scanf("%d", &N); stack<command> commands; commands.push(command(false, N, 'a', 'b', 'c')); while(!commands.empty()) { command curCommand = commands.top(); commands.pop(); if(curCommand.move) { printf("%c -> %c\n", curCommand.a, curCommand.c); } else { if(curCommand.n >= 1) { commands.push(command(false, curCommand.n - 1, curCommand.b, curCommand.a, curCommand.c)); commands.push(command(true, curCommand.n, curCommand.a, curCommand.b, curCommand.c)); commands.push(command(false, curCommand.n - 1, curCommand.a, curCommand.c, curCommand.b)); } } } return 0; }
C++解題報告: