汉诺塔问题

#include <iostream>

void hanoi(int n, char source, char target, char auxiliary) {
	if (n > 0) {
		// 将 n-1 个盘子从 source 移动到 auxiliary,使用 target 作为辅助
		hanoi(n - 1, source, auxiliary, target);
		// 将最大的盘子从 source 移动到 target
		std::cout << "Move disk " << n << " from " << source << " to " << target << std::endl;
		// 将 n-1 个盘子从 auxiliary 移动到 target,使用 source 作为辅助
		hanoi(n - 1, auxiliary, target, source);
	}
}

int main() {
	int n = 3; // 盘子数量
	hanoi(n, 'A', 'C', 'B'); // 从塔座A移动到塔座C,使用塔座B作为辅助
	return 0;
}

 递归栈的过程:

初始调用:
调用 hanoi(3, 'A', 'C', 'B'),将参数 n=3, source='A', target='C', auxiliary='B' 和函数返回地址压入栈中。
第一次递归调用:
在 hanoi(3, 'A', 'C', 'B') 函数内部,因为 n > 0,执行递归调用 hanoi(2, 'A', 'B', 'C')。
将参数 n=2, source='A', target='B', auxiliary='C' 和函数返回地址压入栈中。
第二次递归调用:
在 hanoi(2, 'A', 'B', 'C') 函数内部,再次因为 n > 0,执行递归调用 hanoi(1, 'A', 'C', 'B')。
将参数 n=1, source='A', target='C', auxiliary='B' 和函数返回地址压入栈中。
最底层递归调用:
在 hanoi(1, 'A', 'C', 'B') 函数内部,因为 n - 1 为 0,不再递归,直接执行打印操作 Move disk 1 from A to C。
函数执行完毕,弹出栈顶的 hanoi(1, 'A', 'C', 'B') 的相关信息,并返回到上一层调用。
返回到第二次递归调用:
继续执行 hanoi(2, 'A', 'B', 'C') 中剩余的操作,打印 Move disk 2 from A to B。
执行递归调用 hanoi(1, 'C', 'B', 'A')。
将参数 n=1, source='C', target='B', auxiliary='A' 和函数返回地址压入栈中。
再次最底层递归调用:
在 hanoi(1, 'C', 'B', 'A') 函数内部,直接执行打印操作 Move disk 1 from C to B。
函数执行完毕,弹出栈顶的 hanoi(1, 'C', 'B', 'A') 的相关信息,并返回到上一层调用。
返回到第一次递归调用:
继续执行 hanoi(2, 'A', 'B', 'C') 中剩余操作,打印 Move disk 1 from A to C。
函数执行完毕,弹出栈顶的 hanoi(2, 'A', 'B', 'C') 的相关信息,并返回到最初的调用。
返回到初始调用:
继续执行 hanoi(3, 'A', 'C', 'B') 中剩余操作,打印 Move disk 3 from A to C。
执行递归调用 hanoi(2, 'B', 'C', 'A')。
后续的递归调用与返回:
hanoi(2, 'B', 'C', 'A') 会继续递归调用 hanoi(1, ...) 和 hanoi(0, ...) 直到所有的盘子都被正确移动到目标塔座。
在这个过程中,每次递归调用都会将相关信息压入栈中,每次递归返回都会从栈中弹出相关信息。
最终结束:
当所有的递归调用都执行完毕并返回后,hanoi(3, 'A', 'C', 'B') 也执行完毕,栈中不再有任何关于这个递归过程的信息,程序结束。

posted on 2024-04-27 14:50  不是小朋友L  阅读(7)  评论(0编辑  收藏  举报

导航