1. 程式人生 > >資料結構與演算法題目集7-17——漢諾塔的非遞迴實現

資料結構與演算法題目集7-17——漢諾塔的非遞迴實現

我的資料結構與演算法題目集程式碼倉: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++解題報告: