新聞中心
C語(yǔ)言漢諾塔程序
將以下內(nèi)容全部復(fù)制到新建的源文件中:(本人自己寫的,因?yàn)槟隳钦n本上的代碼,沒解釋,書寫不規(guī)范,很難理解清楚,所以我直接新寫了一個(gè)完整的代碼,附帶詳細(xì)說(shuō)明)
成都創(chuàng)新互聯(lián)主營(yíng)唐縣網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app開發(fā),唐縣h5微信小程序開發(fā)搭建,唐縣網(wǎng)站營(yíng)銷推廣歡迎唐縣等地區(qū)企業(yè)咨詢
#include stdio.h
//漢諾塔x層塔從A塔整體搬到C塔,中間臨時(shí)B塔。
//x層塔是從大到小往上疊放。每次移動(dòng)只能移動(dòng)一層塔。并且在移動(dòng)過(guò)程中必須保證小層在上邊
//借助B塔可以將x層塔全部從A搬到C上,并且符合要求(在移動(dòng)過(guò)程中大的那塊在下邊,小的那塊在上邊)
int main()
{
void tower(int x,char a,char b,char c); //聲明函數(shù)
int x=5,a='A',b='B',c='C'; //x表示有5層塔,具體要多少層自己修改這個(gè)值。abc分別表示ABC塔。
tower(x,a,b,c); //x層塔從a移動(dòng)到c的全過(guò)程,主程序只有這條有效語(yǔ)句
return 0;
}
//以下是tower函數(shù)的定義
//參數(shù)解析:x層塔放在a上,b是中間塔,c是目標(biāo)塔。即x層塔要從a搬到c上。
//此函數(shù)實(shí)現(xiàn)x層塔從a整體轉(zhuǎn)移到c上。以及這個(gè)過(guò)程是怎么搬的全部過(guò)程。
void tower(int x,char a,char b,char c)
{
if(x==1)printf("將%d從%c放到%c\n",x,a,c); //只有1層塔時(shí),直接從a搬到c上。
else //不止1層塔,則先將x-1層塔從a按照規(guī)律搬到b上,再將最后一塊從a搬到c上,最后再將b上的x-1層塔按照規(guī)律搬到c上。
{
tower(x-1,a,c,b); //先將x-1層塔從a按照規(guī)律搬到b上,注意參數(shù)b放在最后,因?yàn)榉旁谧詈蟮膮?shù)是準(zhǔn)備搬過(guò)去的目標(biāo)塔。
printf("將%d從%c放到%c\n",x,a,c); //將最后一塊從a搬到c上
tower(x-1,b,a,c); //最后再將b上的x-1層塔按照規(guī)律搬到c上,注意參數(shù)b放在開頭,因?yàn)閤-1層是要從b上搬過(guò)去的。
}
}
求C漢諾塔遞歸過(guò)程詳解
解決漢諾塔的基本思想是先把n個(gè)盤子除了最下面的盤子以外的所有盤子從第一根柱子(初始柱子)移動(dòng)到中間那個(gè)柱子上(輔助柱子),然后把最下面的盤子移動(dòng)到最后一根柱子上(目標(biāo)柱子)。最后把剩下的盤子移動(dòng)到目標(biāo)柱子上。這樣,然而,完成第一步和第三步也同樣是一個(gè)移動(dòng)n-1個(gè)盤子的漢諾塔問(wèn)題。于是,遞歸調(diào)用在這里不可避免。程序你已經(jīng)寫的很清楚,給你解釋一下。現(xiàn)把你的程序畫上行以便說(shuō)明。
1 #include "stdio.h"
2 main()
3 {void hanoi(int,char,char,char); br/4 int m; br/5 printf("input the number of disks:"); br/6 scanf("%d",m); br/7 printf("The step to moving %d disks:\n",m); br/8 hanoi(m,'A','B','C'); br/9 }
10 void hanoi(int n,char a,char b,char c)
11 {//void move(char,char);
12 if(n==1) move(a,c);
13 else
14 {hanoi(n-1,a,c,b); br/15 move(a,c); br/16 hanoi(n-1,b,a,c); br/17 }
18 }
19 void move(char x,char y)
20 {printf("%c--%c\n",x,y); br/21 }
當(dāng)m=4時(shí),程序走到第8行,調(diào)用函數(shù)hanoi(int n,char a,char b,char c)。此時(shí),實(shí)參把值傳遞給了形參,于是此時(shí),n=4,a=A,b=B,c=C。我把第11行的void move(char,char); 注釋掉了,應(yīng)該知道這一句的意思。因?yàn)檫@一行雖然可以讓程序更加完整,但是解釋的時(shí)候加上它會(huì)很麻煩。程序走到第12行,因?yàn)榇藭r(shí)n=4,而不等于1,程序直接走第13行。于是調(diào)用第14行的hanoi(n-1,a,c,b)。這是一個(gè)遞歸調(diào)用。此時(shí),n=3,a=A,c=B,b=C。要清楚,A,B,C代表的意義。A代表初始柱子,B代表輔助柱子,C代表目標(biāo)柱子。而a代表第一根柱子,b代表第二根柱子,c代表第三根柱子。這是不一樣的。程序繼續(xù)走,到12行時(shí)n依然不等于1。走到14行調(diào)用hanoi(n-1,a,c,b)。此時(shí),n=2,a=A,c=C,b=B。程序再走,到12行時(shí)n依然不等于1,走到14行調(diào)用hanoi(n-1,a,c,b)。此時(shí),n=1,a=A,c=B,b=C。程序走到12行時(shí)發(fā)現(xiàn)n=1,程序開始走15行。調(diào)用move(char x,char y)到20行時(shí)輸出A--B。調(diào)用結(jié)束,回到上一個(gè)調(diào)用即n=2,a=A,c=C,b=B。程序回到第15行,輸出 A--B。再走第16行,調(diào)用hanoi(n-1,b,a,c)。此時(shí)n=1,b=A,a=B,c=C。程序回到12行再調(diào)用19行輸出B--C。調(diào)用結(jié)束,回到上一個(gè)調(diào)用n=3,a=A,c=B,b=C。程序走到15行,輸出A--C,這時(shí),第一根柱子上有一個(gè)盤子,第二根柱子上有一個(gè)盤子,第三根柱子上有兩個(gè)盤子。再調(diào)用16行就可以完成把第三根柱子里的所有盤子都移動(dòng)到第二根柱子上。這樣。我們就完成了整體目標(biāo)的第一步。把n個(gè)盤子除了最下面的盤子以外的所有盤子從第一根柱子(初始柱子)移動(dòng)到中間那個(gè)柱子上(輔助柱子),調(diào)用完成后程序回到15行,此時(shí)n=3,a=A,c=B,b=C。15行時(shí)輸出A--C,這時(shí)便完成了整體目標(biāo)的第二步,最下面的盤子移動(dòng)到最后一根柱子上(目標(biāo)柱子)。再根據(jù)程序走到16行,經(jīng)過(guò)跟14行類似的一系列的遞歸調(diào)用,我們就可以完成最終目標(biāo)了。
怎樣用c語(yǔ)言圖形演示漢諾塔
#include graphics.h
struct H
{
int data[15];/*存放每個(gè)盤的代號(hào)*/
int top;/*每個(gè)塔的具體高度*/
}num[3];/*三個(gè)塔*/
void move(char x,char y,struct H num[3]);/*移動(dòng)的具體過(guò)程*/
void hanoi(char x,char y,char z,int n,struct H num[3]);/*遞歸*/
void Init(void);/*初始化*/
void Close(void);/*圖形關(guān)閉*/
int computer=1;/*自動(dòng)控制與手動(dòng)控制的標(biāo)志*/
int speed=0;/*全局變量speed主要是演示過(guò)程的速度*/
void main(void)
{
Init();/*初始狀態(tài)*/
Close();/*圖形關(guān)閉*/
exit(0);
}
void Init(void)/*初始化*/
{
int gd=DETECT,gm;
int i,n,color;
clrscr();
printf("please input n(n=10): ");/*輸入要演示的盤子數(shù)*/
scanf("%d",n);
printf("Please input 1 or 2:\n1點(diǎn)抗 puter 2.people\n");
scanf("%d",i);
if(i==2)/*選擇手動(dòng)控制標(biāo)志為0*/
computer=0;
if(n1||n10)
n=10;/*越界的話n當(dāng)10處理*/
if(computer)/*如果是自動(dòng)控制的話輸入速度*/
{
printf("please input speed: ");/*輸入速度*/
scanf("%d",speed);
}
initgraph(gd,gm,"c:\\tc");
cleardevice();
for(i=0;i3;i++)
num[i].top=-1;/*三個(gè)地方的高度開始都為-1*/
for(i=0;in;i++)/*畫一開始的塔座A上的盤子*/
{
num[0].top++;/*棧的高度加1*/
num[0].data[num[0].top]=i; /*最大的盤子代號(hào)為0,依次為1,2,…n-1*/
color=num[0].data[num[0].top]+1;/*盤子的顏色代碼為棧頂盤子代號(hào)加1*/
setfillstyle(SOLID_FILL,color);
bar(100-(33-3*num[0].data[num[0].top]),400-20*i-8,100+
(33-3*num[0].data[num[0].top]),400-20*i+8); /*畫矩形*/
}
setcolor(YELLOW);
outtextxy(180,450,"any key to continue");
settextstyle(0,0,2);
outtextxy(90,420,"A"); /*塔座標(biāo)志*/
outtextxy(240,420,"B");
outtextxy(390,420,"C");
getch();/*接收字符后就執(zhí)行遞歸操作*/
hanoi('a','b','c',n,num);
}
void move(char x,char y,struct H num[3])/*移動(dòng)的具體過(guò)程*/
{
int i;
char num1[3],num2[3];
sprintf(num1,"%c",x-32);/*將小寫變成大寫,并轉(zhuǎn)換成字符串輸出*/
sprintf(num2,"%c",y-32);
setfillstyle(SOLID_FILL,BLACK);/*把原來(lái)的地方移去涂黑*/
bar(0,0,640,60);
setcolor(RED);
outtextxy(150,30,num1);/*輸出移動(dòng)過(guò)程*/
outtextxy(200,30,"---");
outtextxy(310,30,num2);
settextstyle(0,0,2);
setfillstyle(SOLID_FILL,BLACK);/*把原來(lái)的地方移去涂黑*/
bar(100+150*(x-97)-(33-3*num[x-97].data[num[x-97].top]),
400-20*num[x-97].top-8,100+150*(x-97)+(33-3*
num[x-97].data[num[x-97].top]),400-20*num[x-97].top+8);
num[y-97].top++;/*入棧,目標(biāo)點(diǎn)的top加1*/
num[y-97].data[num[y-97].top]=num[x-97].data[num[x-97].top];/*在目標(biāo)點(diǎn)盤子的代號(hào)與源點(diǎn)盤子的代號(hào)相同*/
num[x-97].top--;/*出棧,原來(lái)地方的top減1*/
setfillstyle(SOLID_FILL,num[y-97].data[num[y-97].top]+1);/*盤子顏色代碼是棧頂盤子代號(hào)加1*/
bar(100+150*(y-97)-(33-3*num[y-97].data[num[y-97].top]),
400-20*num[y-97].top-8,100+150*(y-97)+
(33-3*num[y-97].data[num[y-97].top]),400-20*num[y-97].top+8);
if(computer)/*自動(dòng)控制就用delay*/
delay(speed);/*延時(shí)函數(shù)*/
else
getch();/*手動(dòng)控制的話就自己按鍵盤來(lái)控制*/
}
void hanoi(char one,char two,char three,int n,struct H num[3])/*遞歸n為盤子數(shù),num為堆棧*/
{
if(n==1)
move(one,three,num);/*如果盤子為1,將這個(gè)盤子從塔座A移動(dòng)到塔座C*/
else
{
hanoi(one,three,two,n-1,num);/*將塔座A的前n-1個(gè)盤子移到塔座B*/
move(one,three,num);/*將塔座A的第n個(gè)盤子移到塔座C*/
hanoi(two,one,three,n-1,num); /*將塔座B的n-1個(gè)盤子移到塔座C*/
}
}
void Close(void)/*圖形關(guān)閉*/
{
getch();
closegraph();
}
網(wǎng)站欄目:漢諾塔c語(yǔ)言函數(shù)圖 漢諾塔c語(yǔ)言程序代碼
標(biāo)題路徑:http://fisionsoft.com.cn/article/ddihdgo.html