從漢諾塔看遞迴

2021-10-12 16:29:17 字數 3629 閱讀 7175

很開心今天搞明白了漢諾塔的方法遞迴。走了很多的彎路,今天分享自己的一些思考的過程以及結果。希望對有需要的同學們有所幫助。

題目:漢諾塔由三根柱子(分別用x、y、z表示)和n個大小互不相同的空心盤子組成。一開始n個盤子都摞在柱子x上,大的在下面,小的在上面,形成了乙個塔狀的錐形體。 對漢諾塔的一次合法的操作是指:從一根柱子的最上層拿乙個盤子放到另一根柱子的最上層,同時要保證被移動的盤子一定放在比它更大的盤子上面(如果移動到空柱子上就不需要滿足這個要求)。現在想要將盤子通過合法的操作從x移到z。要求能顯示碟片在移動中的每一搬動的走向。–題目出處來自由武漢大學出版社出版的**《c語言程式設計》**–主編 高建華 等教授們。

#include

#include

void

move

(int n,

char s,

char d)

;void

hanoi

(int n,

char x,

char y,

char z)

;int

main

(void

)void

hanoi

(int n,

char x,

char y,

char z)

}void

move

(int n,

char s,

char d)

#include

#include

//c語言的乙個標頭檔案,conio是consoleinput/output(控制台輸入輸出)的簡寫,其中定義了通過控制台進行資料輸入和資料輸出的函式,主要是一些使用者通過按鍵盤產生的對應操作,比如getch()函式等等。具體涉及哪些函式我會在下面進行簡單的補充,因為我對這方面也不是太明白,大家有需要的可以在csdn上看其他人的文章。//

void move(int n,char s,char d);

void hanoi(int n,char x,char y,char z);

//函式的使用前先宣告,如果函式定義在主函式之前就不要再申明了(變相的宣告),記住一定要在前面定義和申明必須有乙個(當然也有在主函式裡宣告,但也是在主函式開頭)//

int main(void)

void hanoi(int n,char x,char y,char z)

}void move(int n,char s, char d)

//對於這段**我之所以會困擾一段時間,是因為誤入了乙個誤區,就是我試圖和計算機一樣一步一步的去執行去推導結果,往往因為資料太大而不了了之。而後我又嘗試自己畫了畫試圖直接將n推到1,結果也是因為,操作不易而放棄。歸根結底我之所以,會犯錯,就是因為沒有真正理解遞迴的本質。//

//遞迴不就是n到n-1嘛,對只是沒錯的,而且是本質,但是很容易在寫**中忘卻這一本質,拿我來說,試圖從n來直接推。hanoi( n, x, y,z)寫出來的就是將n個盤子從x移到z,你先別管函式裡到底是啥步驟,就是乙個黑盒子,裡面就像是有魔法,一下子就實現了。 所以hanoi(n-1,x,z,y);這個就是將上面的n-1塊盤子通過魔法的力量直接轉移到y這個柱子上,那麼x上不就剩一塊了麼,於是就直接搬到z就是了。再 hanoi(n-1,y,x,z);將之前的n-1塊搬到z上就行了。那可能會有同學問了,hanoi(n-1,x,z,y)這個又是咋將n-1塊搬走的呢?回答因為有魔法,嘿嘿(自動狗頭保命)。其實這裡的魔法就是遞迴的作用,你不要糾結他到底咋遞迴的,你只要明白用了這個函式就可以實現,至於咋實現的。不要管他。那總不能啥都不管吧。管還是要管的,管的是啥,管的是起始項。

那啥是起始項。就是下面的n=2時。即x上只有2塊盤子,將這兩塊盤子從x移到z,借用y來實現,這個就比較簡單了。畫圖就ok了。自己動動手。

hanoi(1,x,z,y);

move(2,x,z);

hanoi(1,y,x,z); //

總而言之,遞迴就是在該函式定義時,呼叫該函式,但往往伴隨n這種變數的變化。遞迴就像是第一數學歸納法一樣,只要你將原有的基石打好就行了。只不過遞迴往往是從n推到1,而第一數學歸納法就k推到k+1;記住不要糾結中間到底有啥步驟,就當成黑盒子,變數一走就達到我們理想的結果。好了,今天就遞迴到這。我去複習c語言了。還有10天考試。加油!!!

下面是包含的常用函式:

cgets(char*);;

cputs(constchar*);

cscanf(constchar*,...);

inpw(unsignedshort);

getch(void);

getche(void);

kbhit(void);

outp(unsignedshort,int);

outpw(unsignedshort,unsignedshort);

putch(int);

ungetch(int);

void_cdeclclreol(void);

void_cdeclclrscr(void);

void_cdecldelline(void);

int_cdeclgettext(intleft,inttop,intright,intbottom,void*destin);

void_cdeclgettextinfo(structtext_info*r);

void_cdeclgotoxy(intx,inty);

void_cdeclhighvideo(void);

void_cdeclinsline(void);

void_cdecllowvideo(void);

int_cdeclmovetext(intleft,inttop,intright,intbottom,intdestleft,intdesttop);

void_cdeclnormvideo(void);

int_cdeclputtext(intleft,inttop,intright,intbottom,void*source);

void_cdecltextattr(intnewattr);

void_cdecltextbackground(intnewcolor);

void_cdecltextcolor(intnewcolor);

void_cdecltextmode(intnewmode);

int_cdeclwherex(void);

int_cdeclwherey(void);

void_cdeclwindow(intleft,inttop,intright,intbottom);

char*_cdeclcgets(char*str);

int_cdeclcprintf(constchar*format,...);

int_cdeclcputs(constchar*str);

int_cdeclcscanf(constchar*format,...);

int_cdeclgetch(void);

int_cdeclgetche(void);

char*_cdeclgetpass(constchar*prompt);

int_cdeclkbhit(void);

int_cdeclputch(intc);

int_cdeclungetch(intch);

從漢諾塔問題看遞迴

看 資料結構,演算法與應用c 語言描述 一文中第185頁出現了乙個漢諾塔問題。這是個遞迴問題,想了好久終於在今天想懂了一點點 用起來說實在的還是濛濛的 include include include using namespace std void move int n,int x,int y,in...

漢諾塔 遞迴

個人理解遞迴函式的基本要求就是,函式中呼叫函式本身,滿足特定的條件後返回。include include include include include include include include include include include include include 標頭檔案引用的較多...

遞迴漢諾塔

遞迴問題 遞迴要有三個要素 1.遞迴結束條件 2.遞迴結束時的處理 3.抽取重複的邏輯,剝離外殼 重點都在這一步 漢諾塔問題 把圓盤從下面開始按大小順序重新擺放在另一根柱子上。且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動乙個圓盤。首先,要搞這個編碼得要知道漢諾塔的解題思路 1.把a塔上...