c語言hanoi塔問題程式中,c語言hanoi塔問題程式中hanoi n 1,one,three,two 的執行過程是怎麼的?

2022-01-01 08:00:01 字數 6640 閱讀 4841

1樓:匿名使用者

要看懂遞迴程式,往往應先從最簡單情況看起。

先看hanoi(1, one, two, three)的情況。這時直接將one柱上的一個盤子搬到three柱上。注意,這裡one柱或three柱到底是a、b還是c並不重要,要記住的是函式第二個引數代表的柱上的一個盤被搬到第四個引數代表的柱上。

為方便,將這個動作記為:

one =》three

再看hanoi(2, one, two, three)的情況。考慮到hanoi(1)的情況已經分析過了,可知這時實際上將產生三個動作,分別是:

one =》two

one =》three

two =》three

很顯然,這實際上相當於將one柱上的兩個盤直接搬到three柱上。

再看hanoi(3, one, two, three)的情況。分析

hanoi(2, one , three, two)

one =》three

hanoi(2, two, one, three)

即:先將one柱上的兩個盤搬到two柱上,再將one柱上的一個盤搬到three柱上,最後再將two柱上的兩個盤搬到three柱上。這不就等於將one柱上的三個盤直接搬到three柱上嗎?

運用歸納法可知,對任意n,

hanoi(n-1, one , three, two)

one =》three

hanoi(n-1, two, one, three)

就是先將one柱上的n-1個盤搬到two柱上,再將one柱上的一個盤搬到three柱上,最後再將two柱上的n-1個盤搬到three柱上。這就是我們所需要的結果!

2樓:撿到的幸福

n就是一個狀態傳給了hanoi函式,即使hanoi沒有返回值,hanoi內部根據n的值也能判斷狀態

3樓:匿名使用者

同學,其實遞迴這個方法,好處就是不需要想的太多,你只需要幹兩件事。

1.確定這個問題可以利用遞迴劃分為更小的同型別的問題2.你寫的遞迴函式確實能將該問題劃分為更小的同型別問題以你的問題為例

void hanoi(int n,char one,char two,char three)//n是加上該盤子,上面還有n個盤子,one,two,three分別代表第一(盤子當前位置),第二(過渡用的位置),第三個位置(目標位置)(相對的)。

if(n==1)

move(one,three);

如果只有一個盤子,直接從1(當前位置)移動到3(目標位置)else

否則,他上面一定有小盤子擋住他了,所以,你需要做的就是將他上面的所有小盤子(1)移到過渡位置(2),將他從當前位置(1)移動到目標位置(3),再將那些小盤子都從過渡位置(2)移動到目標位置(3)。而你寫的hanoi函式,就是用於解決將當前位置的一堆盤子移動到目標位置的函式。

4樓:遙遠的守望

通過 單目除錯 能很清楚的看到其中的執行過程

5樓:

通過判斷n是不是大於1來遞迴

6樓:

my name is liao yu bing

c語言函式遞迴呼叫漢諾塔問題

7樓:

我一步步的給你講,就會懂啦:

首先hanoi函式如果把當中的move函式給去掉,就變成了:

void hanoi(int n, char one , char two, charthree)

}也就是把move(one,three),變成了printf("%c->%c\n", one, three);。少了一個函式,更加清晰

所以這裡的hanoi函式就有了執行的內容:printf

下面以3個盤子為例進行模擬計算機的執行過程:

1、hanoi(3,a,b,c),開始了這步,進入第一層函式,計算機在函式中會進行自我的再次呼叫(第7行**)

2、(第7行):hanoi(2,a,c,b),於是這又是一個新的hanoi函式,這裡我把它成為第二層函式

同樣執行到第7行,卡住了,再次一次自我的呼叫

3、(進入第三層函式):hanoi(1,a,b,c),這裡的第三層n=1,所以在第四行就顯示出了"a->c",至此,第三層函式結束,回到呼叫他的第二層函式

4、在第二層當中,繼續第8行的內容,所以顯示出"a->b",繼續執行,到第9行,開始了有一次自我呼叫

5、把她稱為貳號第三層函式吧。。。hanoi(1,b,a,c),和第3步類似,這一層函式顯示出了"b->c",然後結束函式,返**用它的第二層函式

6、第二層函式執行完畢,返**用它的第一層函式

7、第一層函式中執行到第8行,顯示出"a->c",然後執行第9行:hanoi(2,b,a,c)

............

如果看到了這裡理清楚了關係就會懂啦,接下來還有一半,如果都寫下來就太複雜了-。-

你所說的空函式是指沒有返回值,但是這裡利用的是電腦呼叫函式的那種關係來解決的問題,比如上面的3步,會自動返回到第二層函式並繼續

還可以這樣理解漢諾塔,漢諾塔其實是將複雜的問題簡單化,

先不管他有多少個盤子從a到c,我只把它視作3步

就像上面那樣找個例子,反覆的按照**模擬計算機執行,過個五次六次,就會懂啦

8樓:谷歌地

#include

void move(int n,char a,char b,char c)

}main()

9樓:匿名使用者

這個程式是一個遞迴程式,並不是直接出結果的,我簡單解釋下好了

首先你要明白函式呼叫過程,比如:

……fun();

a++;

……在這個例子中,fun結束了會執行a++這種語句,這點沒問題吧。遞迴函式會重複呼叫同名的函式,但是不代表退出了一個同名函式就直接退出了整個函式,而是一層層的返回的。

//取n=3

hanoi(3,'a','b','c');//main中呼叫

hanoi(2,'a','c','b');//n=3,執行else

hanoi(1,'a','b','c');//n=2,執行else

move('a','c');//n=1,執行if,完畢後return到呼叫出執行下一句

move('a','b');//else中第二句

hanoi(1,'c','a','b');//else中第三句

move('c','b');//返**用處,但hanoi(2,'a','c','b')也執行完畢,繼續返回

move('a','c');

hanoi(2,'b','a','c');

hanoi(1,'b','c','a');

move('b','a');

move('b','c');

hanoi(1,'a','b','c');

move('a','c');

//返回至hanoi(1,'a','b','c');

//返回至hanoi(2,'b','a','c');

//返回至main中呼叫hanoi(3,'a','b','c');

遞迴雖然有點抽象,但還是按照函式呼叫的規則的,都是呼叫,結束返回到呼叫處。剛開始都是過程,直到遇到了遞迴結束條件,才結束遞迴呼叫的過程

你這裡的遞迴函式並不是你說的空函式,你仔細看下在這個函式執行過程中,肯定有某些語句是起作用的,你這裡就是move起作用了,你仔細理解下

10樓:

這個遞迴根本就不需要運算,如果你非要理解成一定要有運算的話,那他那個輸出就算是運算了,只是遞迴呼叫的時候是根據上一層遞迴而改變的,主要還是你要理解這個演算法的邏輯過程,而不是糾結於怎麼運算,在紙上一步一步演算一下你就會懂得。

11樓:朝陽

先呼叫一次hanoi(m,'a','b','c'),其中引數m是你輸入的值.

如果你輸入的m為1,則直接呼叫move(one,three),然後直接輸入 a-->c換行

如果你輸入的m不為1,假設為2,則執行過程如下

執行一次hanoi(1,one,three,two),執行 move(one,three),然後直接輸出a-->b換行

執行一次move(one,three),然後直接輸出 a-->c換行

執行一次hanoi(1,two,one,three),執行move(one,three),然後直接輸出b-->c換行

如果你輸入的數字》2那就相應的進入到更多層的hanoi()函式中迴圈

12樓:聽不清啊

void move ( char x, char y )    //完成一個盤子從x 移到 y

13樓:清蓮玉

move函式有實際作用啊。

求真正理解漢諾塔問題的程式設計大神回答一下,當n=3時,用c語言編寫的漢諾塔遞迴呼叫**的詳細執行過程

14樓:汗會欣

/* 漢諾塔 hannota.c */

#include

/*解法:

如果柱子標為abc,要由a搬至c,在只有一個盤子時,就將它直接搬至c,當有兩個盤子,就將b當作輔助柱。

如果盤數超過2個,將第三個以下的盤子遮起來,就很簡單了,每次處理兩個盤子,也就是:a->b、a->c、b->c這三個步驟,而被遮住的部份,其實就是進入程式的遞迴處理。

事實上,若有n個盤子,則移動完畢所需之次數為2^n-1;

所以當盤數為64時,則 64所需次數為:2^63=8446744073709551615為5.05390248594782e+16年,

也就是約5000世紀,如果對這數字沒什么概念,就假設每秒鐘搬一個盤子好了,也要約5850億年左右

*/void hannota ( int n,char a,char b,char c )

else

}int main()

15樓:我愛上那女孩

一開始我接觸漢諾塔也是很不解,隨著**量的積累,現在很容易就看懂了,因此樓主主要還是對遞迴函式的理解不夠深刻,建議你多寫一些遞迴程式,熟練了自己就能理解。

圓盤邏輯移動過程+程式遞迴過程分析

hanoi塔問題, 演算法分析如下,設a上有n個盤子,為了便於理解我將n個盤子從上到下編號1-n,標記為盤子1,盤子2......盤子n。

如果n=1,則將「 圓盤1 」 從  a 直接移動到 c。

如果n=2,則:

(1)將a上的n-1(等於1)個圓盤移到b上,也就是把盤1移動到b上;

(2)再將a上 「盤2」 移到c上;

(3)最後將b上的n-1(等於1)個圓盤移到c上,也就是第(1)步中放在b上的盤1移動到c上。

注意:在這裡由於超過了1個盤子,因此不能直接把盤子從a移動到c上,要藉助b,那 麼 hanoi(n,one,two,three)的含義就是由n個盤子,從one移動到three,如果n>2 那麼就進行遞迴,如果n=1,那麼就直接移動。

具體流程:

hanoi(2,a,b,c);由於2>1因此進入了遞迴的環節中。

<1>執行hanoi(1,a,c,b):這裡就是剛才的步驟(1),代表藉助c柱子,將a柱子上的  1個圓盤(盤1)移動到b柱子,其實由於是n=1,此時c柱子並沒被用到,而是直接移動了。

<2>執行hanoi(1,a,b,c):這是步驟(2),藉助b柱子,將a柱子上的一個圓盤(盤2)移動到c柱子上。這裡由於也是n=1,也並沒有真正藉助b柱子,直接移動的。

<3>執行hanoi(1,b,a,c):這是步驟(3),將b上的一個盤子(盤1)移動到c

函式中由於每次呼叫hanoi的n值都是1,那麼都不會進入遞迴中,都是直接執行了mov移動函式。

如果n=3,則:(倒著想會想明白)移動的倒數第二部,必然是下面的情況

(1)將a上的n`-1(等於2)個圓盤移到c上,也就是將盤1、盤2 此時都在b柱子上,只有這樣才能移動最下面的盤子(盤3)。那麼由於現在我們先忽略的最大的盤子(盤3),那麼我們現在的目標就是,將兩個盤子(盤1、盤2)從a柱子上,藉助c柱  子,移動到b柱子上來,這個過程是上面n=2的時候的移動過程,n=2的移動過程是「2     個盤子,從柱子a,藉助柱子b,移動到柱子c」。現在是「2個盤子,從柱子a,藉助柱子 c,移動到柱子b上」。

因此移動過程直接呼叫n=2的移動過程就能實現。

(2)將a上的一個圓盤(盤3)移到c。

(3)到這一步,由於已經將最大的盤子(盤3)移動到了目的地,此時無論後面怎麼移動都不需要在用到最大的那個盤子(盤3),我們就先忽略他,剩下的目標就是將b上面的n-1個盤子(盤1、盤2)移動到c上,由於a上沒有盤子了,此時要完成上面的目標,就要藉助a盤子。最終達到的目標就是將b上的2個盤子,藉助a移動到c上,這個過程就是當n=2時分析的過程了,僅僅是最開始的柱子(b柱子)和被藉助的柱子(a柱子)不同了。所以直接呼叫n=2時候的過程就能股實現了。

具體執行過程:

hanoi(3,a,b,c);由於3>1因此進入了遞迴的環節中。

<1>執行hanoi(2,a,c,b):這裡代表剛才的步驟(1),將兩個盤子(盤1、盤2)從a移動到b,中間藉助c。根據n=2的分析過程,必然是能夠達到我們的目的。

<2>執行hanoi(1,a,b,c):現在a上只有一個盤子(盤3),直接移動到c上面即可。

<3>執行hanoi(2,b,a,c):此時對應步驟(3),剩下的目標就是將b上的兩個盤子,藉助a移動到c上。那麼同樣根據n=2的移動過程,必然能達到目的。

最終實現了3個盤子從a,藉助b移動到了c。

c語言程式問題,C語言程式問題?

1.在你打算學習c語言之前,你要下一個狠狠地決心.因為許多電腦愛好者在學習c語言的過程中,都會遇到困難,從而沒有堅持到最後.只有你下定狠狠地決心,才能學會c語言,才能學好c語言.2.要想學習好c語言,就要學會細心,耐心.c語言程式的編寫需要非常細心,因為一個標點符號的錯誤,可能導致程式的無法執行.3...

c語言程式問題新手,C語言程式問題 新手

include define n 50 人數 define fl 60 統計分數下限void sort float a,int c 選擇排序return r int main void include stdio.h main printf d num 輸出學生個數 程式比較短,考慮到樓主情況後面追...

c語言漢諾塔的問題,C語言漢諾塔的問題

要看懂遞迴程式,往往應先從最簡單情況看起。先看hanoi 1,one,two,three 的情況。這時直接將one柱上的一個盤子搬到three柱上。注意,這裡one柱或three柱到底是a b還是c並不重要,要記住的是函式第二個引數代表的柱上的一個盤被搬到第四個引數代表的柱上。為方便,將這個動作記為...