例5. 9也可以不用遞歸的方法來(lái)完成。如可以用遞推法,即從1開(kāi)始乘以2,再乘以3…直到n。遞推法比遞歸
法更容易理解和實(shí)現(xiàn)。但是有些問(wèn)題則只能用遞歸算法才能實(shí)現(xiàn)。典型的問(wèn)題是 Hanoi塔問(wèn)題。
[例 5.10]Hanoi塔問(wèn)題
一塊板上有三根針,A,B,C。A針上套有 64個(gè)大小不等的圓盤(pán), 大的在下,小的在上。如圖 5.4所示。要把這 64
個(gè)圓盤(pán)從A針移動(dòng) C針上,每次只能移動(dòng)一個(gè)圓盤(pán),移動(dòng)可以借助 B針進(jìn)行。但在任何時(shí)候,任何針上的圓盤(pán)都必須
保持大盤(pán)在下,小盤(pán)在上。求移動(dòng)的步驟。
本題算法分析如下,設(shè)A上有 n個(gè)盤(pán)子。
如果n=1,則將圓盤(pán)從A直接移動(dòng)到 C。
如果n=2,則:
1.將 A上的n-1(等于 1)個(gè)圓盤(pán)移到B上;
2.再將A上的一個(gè)圓盤(pán)移到 C上;
3.最后將 B上的 n-1(等于 1)個(gè)圓盤(pán)移到C上。
如果n=3,則:
A. 將 A上的n-1(等于2,令其為 n`)個(gè)圓盤(pán)移到B(借助于 C),
步驟如下:
(1)將A上的n`-1(等于1)個(gè)圓盤(pán)移到 C上,見(jiàn)圖5.5(b)。
(2)將A上的一個(gè)圓盤(pán)移到B,見(jiàn)圖 5.5(c)
(3)將C上的n`-1(等于1)個(gè)圓盤(pán)移到B,見(jiàn)圖 5.5(d)
B. 將A上的一個(gè)圓盤(pán)移到C,見(jiàn)圖5.5(e)
C. 將 B上的n-1(等于2,令其為 n`)個(gè)圓盤(pán)移到C(借助 A),
步驟如下:
(1)將B上的n`-1(等于1)個(gè)圓盤(pán)移到A,見(jiàn)圖 5.5(f)
(2)將B上的一個(gè)盤(pán)子移到C,見(jiàn)圖 5.5(g)
(3)將A上的n`-1(等于1)個(gè)圓盤(pán)移到C,見(jiàn)圖5.5(h)。
到此,完成了三個(gè)圓盤(pán)的移動(dòng)過(guò)程。
從上面分析可以看出,當(dāng) n大于等于2時(shí), 移動(dòng)的過(guò)程可分解為
三個(gè)步驟:
第一步 把A上的n-1個(gè)圓盤(pán)移到B上;
第二步 把A上的一個(gè)圓盤(pán)移到C上;
第三步 把B上的n-1個(gè)圓盤(pán)移到C上;其中第一步和第三步是類(lèi)同的。
當(dāng)n=3時(shí),第一步和第三步又分解為類(lèi)同的三步,即把n`-1個(gè)圓盤(pán)從一個(gè)針移到另一個(gè)針上,這里的n`=n-1。顯然
這是一個(gè)遞歸過(guò)
程,據(jù)此算法可編程如下:
move(int n,int x,int y,int z)
{
if(n==1)
printf("%c-->%c\n",x,z);
else
{
move(n-1,x,z,y);
printf("%c-->%c\n",x,z);
move(n-1,y,x,z);
}
}
main()
{
int h;
printf("\ninput number:\n");
scanf("%d",&h);
printf("the step to moving - diskes:\n",h);
move(h,'a','b','c');
}
move(int n,int x,int y,int z)
{
if(n==1)
printf("%-->%c\n",x,z);
else
{
move(n-1,x,z,y);
printf("%c-->%c\n",x,z);
move(n-1,y,x,z);
}
}
main()
{ ……
move(h,'a','b','c');
}
![]() | ![]() .. 定價(jià):¥225 優(yōu)惠價(jià):¥213 更多書(shū)籍 |
![]() | ![]() .. 定價(jià):¥133 優(yōu)惠價(jià):¥133.0 更多書(shū)籍 |