数据结构与算法题目集7-17——汉诺塔的非递归实现

我的数据结构与算法题目集代码仓:https://github.com/617076674/Data-structure-and-algorithm-topic-set

原题链接:https://pintia.cn/problem-sets/15/problems/821

题目描述:

数据结构与算法题目集7-17——汉诺塔的非递归实现_第1张图片

知识点:递归、栈

思路一:递归实现

递归终止条件

当N为1时,直接将一个盘子从a移动到c即可。

递归过程

(1)先将n - 1个盘子从a通过c移动到b。

(2)再将一个盘子从a移动到c。

(3)最后将n - 1个盘子从b通过a移动到c。

时间复杂度和空间复杂度均为O(2 ^ N)。

C++代码:

#include

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++解题报告:

数据结构与算法题目集7-17——汉诺塔的非递归实现_第2张图片

思路二:非递归实现

非递归实现,就是利用我们自己的栈来代替系统栈,这个做法在LeetCode094——二叉树的中序遍历的思路二、LeetCode144——二叉树的前序遍历的思路二、LeetCode145——二叉树的后序遍历的思路二均有涉及。

就是将一条一条的指令压入栈中,当然,需要额外一个一个bool型变量move表示当前命令需不需要移动盘子,输出移动盘子的路径。

注意,命令入栈顺序和递归调用的顺序是相反的。

时间复杂度和空间复杂度均为O(2 ^ N)。

C++代码:

#include
#include

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 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++解题报告:

数据结构与算法题目集7-17——汉诺塔的非递归实现_第3张图片

 

你可能感兴趣的:(数据结构与算法题目集)