首先調(diào)用 hanoi(3,a,b,c)
章丘網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,章丘網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為章丘上千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的章丘做網(wǎng)站的公司定做!
判斷 “3”是否為“1”
不為“1”
{
{ 調(diào)用 hanoi(n-1, one, three, two),即hanoi(2,a,c,b)
執(zhí)行hanoi(2,a,c,b),此時(shí) one = a,two = c,thtee = b;
判斷 “2”是否為“1”,不為1
調(diào)用 hanoi(n-1, one, three, two),即hanoi(1,a,b,c)
執(zhí)行hanoi(1,a,b,c),此時(shí) one = a,two = b,thtee = c;
判斷 “1”是否為“1”,為1,執(zhí)行move(one, three)即move(a, c)
以上為循環(huán)執(zhí)行hanoi(n-1, one, three, two)函數(shù),直到“n==1”
}
執(zhí)行move(one, three);
執(zhí)行hanoi(n-1, two, one, three)
{
循環(huán)執(zhí)行hanoi(n-1, two, one, three),直到“n==1”
}
}
主要是遞歸的用法
好像解釋的不太清楚,但希望能幫到你。
我一步步的給你講,就會(huì)懂啦:
首先hanoi函數(shù)如果把當(dāng)中的move函數(shù)給去掉,就變成了:
void?hanoi(int?n,?char?one?,?char?two,?charthree)
{
if(n?==?1)
printf("%c-%c\n",?one,?three);
else
{
hanoi(n?-?1,?one,?three,?two);
printf("%c-%c\n",?one,?three);
hanoi(n?-?1,?two,?one,?three);
}
}
也就是把move(one,three),變成了printf("%c-%c\n", one, three);。少了一個(gè)函數(shù),更加清晰
所以這里的hanoi函數(shù)就有了執(zhí)行的內(nèi)容:printf
下面以3個(gè)盤(pán)子為例進(jìn)行模擬計(jì)算機(jī)的執(zhí)行過(guò)程:
1、hanoi(3,A,B,C),開(kāi)始了這步,進(jìn)入第一層函數(shù),計(jì)算機(jī)在函數(shù)中會(huì)進(jìn)行自我的再次調(diào)用(第7行代碼)
2、(第7行):hanoi(2,A,C,B),于是這又是一個(gè)新的hanoi函數(shù),這里我把它成為第二層函數(shù)
同樣執(zhí)行到第7行,卡住了,再次一次自我的調(diào)用
3、(進(jìn)入第三層函數(shù)):hanoi(1,A,B,C),這里的第三層n=1,所以在第四行就顯示出了"A-C",至此,第三層函數(shù)結(jié)束,回到調(diào)用他的第二層函數(shù)
4、在第二層當(dāng)中,繼續(xù)第8行的內(nèi)容,所以顯示出"A-B",繼續(xù)運(yùn)行,到第9行,開(kāi)始了有一次自我調(diào)用
5、把她稱(chēng)為貳號(hào)第三層函數(shù)吧。。。hanoi(1,B,A,C),和第3步類(lèi)似,這一層函數(shù)顯示出了"B-C",然后結(jié)束函數(shù),返回調(diào)用它的第二層函數(shù)
6、第二層函數(shù)執(zhí)行完畢,返回調(diào)用它的第一層函數(shù)
7、第一層函數(shù)中執(zhí)行到第8行,顯示出"A-C",然后執(zhí)行第9行:hanoi(2,B,A,C)
............
如果看到了這里理清楚了關(guān)系就會(huì)懂啦,接下來(lái)還有一半,如果都寫(xiě)下來(lái)就太復(fù)雜了-。-
你所說(shuō)的空函數(shù)是指沒(méi)有返回值,但是這里利用的是電腦調(diào)用函數(shù)的那種關(guān)系來(lái)解決的問(wèn)題,比如上面的3步,會(huì)自動(dòng)返回到第二層函數(shù)并繼續(xù)
還可以這樣理解漢諾塔,漢諾塔其實(shí)是將復(fù)雜的問(wèn)題簡(jiǎn)單化,
先不管他有多少個(gè)盤(pán)子從A到C,我只把它視作3步
就像上面那樣找個(gè)例子,反復(fù)的按照代碼模擬計(jì)算機(jī)運(yùn)行,過(guò)個(gè)五次六次,就會(huì)懂啦
見(jiàn)代碼注釋?zhuān)€有不懂可以問(wèn)。
#include?stdio.h
void?move(char?x,char?y)
{
printf("%c--%c\n",x,y);
}
//hannuota函數(shù)的作用:把n個(gè)圓盤(pán)從one柱子借助two柱子放到three柱子?
void?hannuota(int?n,char?one,char?two,char?three)
{
if(n==1)//如果只有一個(gè)柱子?
move(one,three);//直接移動(dòng)即可?
else
{
hannuota(n-1,one,three,two);//先把one柱子上的n-1個(gè)圓盤(pán)借助three柱子移動(dòng)到柱子two?
move(one,three);//把第一個(gè)柱子的剩下那一個(gè)(第n個(gè))移動(dòng)到第三個(gè)柱子
//由于原來(lái)one柱子上的n-1個(gè)圓盤(pán)已經(jīng)移動(dòng)到了two柱子上,因此不會(huì)有圓盤(pán)擋住n圓盤(pán)出來(lái)?
hannuota(n-1,two,one,three);
//最后再把那n-1個(gè)圓盤(pán)從two柱子借助one柱子移動(dòng)到three柱子
//(上面第一句話hannuota(n-1,one,three,two)已經(jīng)移動(dòng)到了two柱子,因此這里是從two柱子移動(dòng)到three柱子)?
}
}
int?main()
{
int?m;
printf("input?the?number?of?diskes:");
scanf("%d",m);
printf("The?step?to?move?%d?diskes:\n",m);
hannuota(m,'A','B','C');
return?0;
}