首页 > 技术文章 > 汉诺塔的非递归实现(栈)

IamIron-Man 2019-11-29 12:17 原文

汉诺塔的非递归实现(栈)

美国学者找的规律:若是偶数,将a、b、c顺时针排列,否则a、c、b排列,然后反复做:

(1)最小盘顺时针移动一个

(2)那两个柱子将最小的移动了,空的话直接移

借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

输入格式:

输入为一个正整数N,即起始柱上的盘数。

输出格式:

每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

输入样例:

3

输出样例:

a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c

美国。看人家递归咋写的吧

#include<iostream>
#include<cstdio>
#include<stack>
#include<cmath>
using namespace std;
int main()
{
//	freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
	int n,num=0,pan1,now;
	long long times;
	char a[3];
	stack <int> ta[3];
	cin>>n;
	for (int i=n;i>=1;i--)
	  ta[0].push(i);
	now=0;
	if (n%2==1)
	{
		a[0]='a';
		a[1]='c';
		a[2]='b';
	}
	else
	{
		a[0]='a';
		a[1]='b';
		a[2]='c';
	}
	times=pow(2,n)-1;
	while (num<times)
	{
		num++;
		pan1=ta[now].top();
		ta[now].pop();
		ta[(now+1)%3].push(pan1);
		printf("%c -> %c\n",a[now],a[(now+1)%3]);
		num++;
		if (num>times)
		  break;
		if (ta[now].size()!=0 and (ta[(now+2)%3].size()==0 or ta[now].top()<ta[(now+2)%3].top()))
		{
			ta[(now+2)%3].push(ta[now].top());
			ta[now].pop();
			printf("%c -> %c\n",a[now],a[(now+2)%3]);
		}
		else
		{
			ta[now].push(ta[(now+2)%3].top());
			ta[(now+2)%3].pop();
			printf("%c -> %c\n",a[(now+2)%3],a[now]);
		}
		now=(now+1)%3;
	}
	return 0;
}

推荐阅读