实验3-1.7 汉诺塔的非递归实现

借助堆栈以非递归(循环)的方式求解汉诺塔问题。

先把十分典型的递归版拿出来:

# include 
void Hanoi(char from, char to, char tmp, int n)
{
	// from: 起始柱名 to:目标柱名 tmp:辅助柱名 n:个数
	if (n == 0) return;

	Hanoi(from, tmp, to, n - 1);
	std::cout << from << " -> " << to << '\n';
	Hanoi(tmp, to, from, n - 1);
}

int main(void)
{
	Hanoi('A', 'C', 'B', 3);
	return 0
}

模拟递归在运行当中在堆栈区层层叠加,就需要有一个栈,存放主调函数和被调函数的信息。信息,用结构体封装。

# include "Stack.h"

struct information {
	char from;
	char to;
	char tmp;
	int n;
};

void Hanoi(char from, char to, char tmp, int n)
{
	Stack<information> s;
	s.push(information{ from, to, tmp, n });
	while (!s.empty())
	{
		information i = s.pop();
		if (i.n-1 > 0) s.push(information{ i.from, i.tmp, i.tmp, i.n-1 });
		std::cout << i.from << " -> " << i.to << '\n';
		if (i.n - 1 > 0) s.push(information{ i.tmp, i.to, i.from, i.n-1 });
	}
}

这样转化的意义在于节省空间。实际上,二者渐近意义上的空间复杂度是不变的,节省的那一部分来自于,递归每次要嵌套,在堆栈区调用一次递归就垒高一次信息,抵达最深时才会返回,所以空间复杂度的常数很大。而尾递归,每调用一个函数就执行完,消除掉当前函数在堆栈区占的位置。所以空间复杂度的常数会变小。

你可能感兴趣的:(ZJU数据结构,算法)