c語言實現漢諾塔(程式執行步驟詳解)
很久沒去接觸c語言了,今天翻了翻c語言的書,偶然間看到了大一時讓我鬱悶了很久的漢諾塔問題,又重新推理了一遍,漢諾塔的實現採用遞迴演算法,涉及到資料結構中的棧的知識。下面是c實現漢諾塔的原始碼。程式只是實現了文字資訊,即用文字描述了圓盤的移動過程,並未真正實現圓盤的移動,該程式難度並不大,要了解遞迴的原理和方法中引數值的變化。
# include <stdio.h>
void hannuota(int n,char one,char two,char three);
void move(char x,char y);
int main(void) {
int n;
printf("please input a integer number:");
scanf("%d",&n);
if(n > 10 || n < 0) {
printf("請輸入一個0~10範圍內的整數!!");
return 0;
}
hannuota(n,'A','B','C');
return 0;
}
void hannuota(int n,char one,char two,char three) {
if(n == 1) {
move(one,three); //<1>
}
else {
hannuota((n-1),one,three,two); //<2>
move(one,three); //<3>
hannuota((n-1),two,one,three); //<4>
}
}
void move(char x,char y) {
printf("%c ----> %c\n",x,y);
}
為了避免執行需要很長的時間,程式限制了輸入的整數大小為0-10,以下是程式執行的順序:(為了篇幅,假設n的值是3)
main方法執行到hannuota(n,'A','B','C')時;該方法裡的引數為hannuota(3,'A','B','C');
1、第一部分:把A柱中的n-1個圓盤藉助C柱移動到B柱
此時執行hannuota方法,因為n=3>1,因此此時遞迴執行hantuona方法,此時方法引數為hannuota(2,'A','C','B'),(注意此時hannuota方法的引數改變了,C和B值互換);因為n=2>1,繼續遞迴呼叫hannuota(1,'A','B','C');(此時hannuota方法的引數改變了,C和B值互換);因為n=1,所以執行move方法,打印出A-->C
返回n=2時程式未執行完的部分,即執行標誌為<3>的move方法,因為此時n=1,打印出A-->B,
繼續執行標誌為<4>的hannuota((n-1),two,one,three)部分,此時引數為hannuota(1,'C','A','B'); 此時n=1,打印出C-->B。到此刻位置標誌為<2>部分的 hannuota((n-1),one,three,two)程式執行完畢。
2、第二部分:把A柱的第n個圓盤移動到C盤
此時直接執行標註為<3>部分的程式move(one,three); 此時打印出A-->C;
3、第三部分:把B柱上的n-1個圓盤藉助A移動到C柱
此時執行標誌為<4>部分的hannuota((n-1),two,one,three),此時引數為hannuota(2,'B','A','C');
因為n=2>1,執行標誌為<2>的程式碼,此時方法引數為hannuota(1,'B','C','A');因為此時n=1,執行標誌為<1>的程式碼,打印出B-->A;此時,標誌為<2>的程式執行完畢,one,two,three的值分別為one=B,two=A,three=C;
繼續執行標誌<3>的程式move(one,three); 打印出B-->C; 繼續執行至標誌<4>的程式碼hannuota((n-1),two,one,three),引數為hannuota(1'A','B','C'),因此n=1,執行標誌<1>的程式碼,打印出A-->C;
到此為止,程式執行完畢。
程式執行結果如下:
A ----> C
A ----> B
C ----> B
A ----> C
B ----> A
B ----> C
A ----> C
漢諾塔問題主要分為以上三個部分,程式中用到了遞迴演算法,遞迴要用到棧的知識,就是進棧和出棧,每到遞迴呼叫一個系統的子系統時,都會為子系統分配記憶體單元,把正被呼叫的子系統壓入棧頂,按照先進後出的規則,執行完後就彈出棧,釋放為其分配的記憶體單元。然後繼續執行棧中的其他部分,直到整個程式執行完畢。