首先必须确定一个移动的方向,比如A->B->C,或者A->C->B,但这个顺序一旦却确定后就不可以再改变了的,否则永远都不会成功。
然后一直按下面两个步骤循环,直到全部完成。
1、把第一片移到下一个位置,比如原来在A,顺序是A->B->C,哪就是移到B,原来在B的就是到C,在C的 就是到A
2、把除第一片以外,可以移动的另外一片移动到可以移动的为止,这个看似模糊,但其实关系是确定的,这个时候只有一片可以移动,而且位置也只有一个可以让它移动。
就是这么两个步骤,用来完成汉诺塔
下面是我的程序
(注:我在程序中作了个弊,如果是奇数片,那顺序一定是A->C->B,(其中A是原柱,B是辅柱,C是目的柱;如果是偶数片,那顺序一定是A->B->C)
#include <stdioh>
//#include <conioh>
//#include <timeh>
#include <dosh>
void henit(int n, char fromreg, char auxreg, char toreg)
{
char heni[255] = {0}, tmptoreg;
int i;
tmptoreg = toreg;
if(n%2)
{
int tmp = auxreg;
auxreg = toreg;
toreg = tmp;
}
for (i=1; i<=n; i++)
{
heni[i] = fromreg;
}
while (1)
{
if (heni[1] == fromreg)
{
heni[1] = auxreg;
printf("\t1: %c-->%c\n", fromreg, auxreg);
}
else
if (heni[1] == auxreg)
{
heni[1] = toreg;
printf("\t1: %c-->%c\n", auxreg, toreg);
}
else
if (heni[1] == toreg)
{
heni[1] = fromreg;
printf("\t1: %c-->%c\n", toreg, fromreg);
}
for (i = 1; heni[i] == tmptoreg && i<=n; i++)
;
if(i>n)
break;
for(i=1;i<=n;i++)
if(heni[i] == fromreg) break;
if(i>n)
{
heni[n+1]=fromreg;
goto Next;
}
for(i=1; i<=n; i++)
if(heni[i] == auxreg) break;
if(i>n)
{
heni[n+1]=auxreg;
goto Next;
}
for(i=1; i<=n; i++)
if(heni[i] == toreg) break;
if(i>n)
{
heni[n+1]=toreg;
goto Next;
}
Next:
for(i=2; heni[i] == heni[1] && i<=n ; i++)
;
for(int j=i+1; j<=n+1; j++)
{
if ((heni[j] != heni[1]) && (heni[j] != heni[i]) && (i<=n))
{
printf("\t%d: %c-->%c\n", i, heni[i], heni[j]);
heni[i] = heni[j];
break;
}
}
}
}
int main(void)
{
int n = 0;
//time_t start_t, end_t;
struct time start_t, end_t;
//clrscr();
printf("Input your number:");
scanf("%d", &n);
//start_t = time(NULL);
gettime(&start_t);
henit(n, 'A', 'B', 'C');
//end_t = time(NULL);
gettime(&end_t);
//printf("Ok,it is down now! use %d seconds", int(end_t - start_t));
printf("Ok,it is down now! use %2d:%02d:%02d%02d", \
(end_tti_hour-start_tti_hour), (end_tti_min-start_tti_min), \
(end_tti_sec-start_tti_sec), (end_tti_hund-start_tti_hund));
getchar();
getchar();
return 0;
}
不要把简单问题复杂化,汉诺塔其实很简单,通过它你关键在理解递归原理就行,何必纠结于这些让人费解的上面的垃圾代码!
汉诺塔程序如下:
#include <iostream>
#include <string>
using namespace std;
int sum=0;
/
为了移动A上面的圆盘到C上面,仅能借助B:
首先由A将n-1个较小的圆盘移至B,
然后将A上剩下的上最大的圆盘移至C,
最后再将B上n-1个较小的圆盘移至C
/
void Hanoi(int n,string A,string B,string C)
{
if(n==1)
cout<<"move "<<A<<" to "<<C<<endl;
else
{
Hanoi(n-1,A,C,B);
cout<<"move "<<A<<" to "<<C<<endl;
Hanoi(n-1,B,A,C);
}
++sum;
}
int main()
{
Hanoi(3,"A","B","C");
cout<<"The sum step is "<<sum<<endl;
return 0;
}
汉诺塔(又称河内塔)问题是印度的一个古老的传说。开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次只能搬一个,而且大的不能放在小的上面。解答结果请自己运行计算,程序见尾部。面对庞大的数字(移动圆片的次数)18446744073709551615,看来,众僧们耗尽毕生精力也不可能完成金片的移动。后来,这个传说就演变为汉诺塔游戏: 1有三根杆子A,B,C。A杆上有若干碟子 2每次移动一块碟子,小的只能叠在大的上面 3把所有碟子从A杆全部移到C杆上经过研究发现,汉诺塔的破解很简单,就是按照移动规则向一个方向移动金片:如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C具体可以参详: >
#include<stdioh>
void move(char a,char b)
{
printf("%c->%c\n",a,b);
}
void f(int n,char a,char b,char c)
{
if(n==1) move(a,c);
else
{
f(n-1,a,c,b);
move(a,c);
f(n-1,b,a,c);
}
}
void main()
{
int n;
scanf("%d",&n);
f(n,'a','b','c');
}
这是我的代码 前面的是定义一个函数 这里递归体现在函数里面还有函数 于是会一次又一次的计算 直到最后把N-1以前的都移到B,最下面的移到C,再把其他的从B移到C。。 无返回的话 应该是这里用void 没有return返回数值
#include <iostream>
using namespace std;
void Hanoi(int, char, char, char);
void move(char, char);
int main()
{ int n;
cout <<"请输入汉诺塔圆盘的个数:";
cin >>n;
Hanoi(n,'A','B','C'); //函数调用
system("pause");
return 0;
}
void Hanoi(int n,char a,char b,char c)
{ if (n==1)
move(a,c); //如果只有两个盘子,只需要移动一次即可;即n=1;
else
{
Hanoi(n-1,a,c,b); //即进行递归,当n=2时,将第一个盘子移到第三个上
move(a,c); //
Hanoi(n-1,b,a,c);//;将第二个盘子移到第三个上,然后继续递归;函数重复 两个盘子时的移动过程;直到n=1,结束;//同样也可以用循环来代替!
}
}
void move(char sour,char dest)
{
cout<<"把"<<sour<<"石柱最上面的圆盘移动到"<<dest<<"圆柱上"<<endl;
}
主要思想是:不管有几个盘子,将一个和其他的看成两部分,然后按照同样的方法移动即可;首先应宁明白二个三个似的的情况,发现规律
以上就是关于求c语言,汉诺塔程序 非递归全部的内容,包括:求c语言,汉诺塔程序 非递归、求Linux下汉诺塔程序详细解释~~、汉诺塔的基本 *** 作步骤是怎样等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)