2011年9月28日 星期三

河內塔程式流程

重新整理河內塔的遞迴順序:







#include <iostream>
using namespace std;
void hanoi(int n,char a,char b,char c)
{
  if(n==1)
  {
    cout<<"將第"<<n<<"盤從"<<a<<"柱搬到"<<c<<"柱"<<endl;
  }
  else
  {
    hanoi(n-1,a,c,b);
    cout<<"將第"<<n<<"盤從"<<a<<"柱搬到"<<c<<"柱"<<endl;
    hanoi(n-1,b,a,c);
  }
}

int main()
{
  int dish;
  cout<<"請輸入盤子的數目"<<endl;
  cin>>dish;
  hanoi(dish,'A','B','C');
  system("pause");    //讓執行後的視窗不會馬上關閉,直到任按一鍵繼續
  return 0;
}

程式的執行順序是這樣子的:
從頭開始:1~2
先執行主程式(行數):17→18→19→20→21→22,
到了22行代入輸入的 dish 盤數到副程式。

副程式部份(行數):
n=3,A B C
3~4:將「3,A B C」代入副程式做呼叫副程式執行。
5:判斷 n 等不等於 1,此時 n=3,不執行 if 內的敘述式。
9~10:由於不執行 if 內的敘述式,所以往 else 來執行。
11:此時再次做副程式呼叫,因為是自己呼叫自己,所以產生「遞迴呼叫」。
n=3-1,A C B
n=2,A C B
3~4~5:從副程式的頭到 if 做判斷 n 等不等於 1,此時 n=2 所以不執行。
9~10:進入到 else 做處理。
11:再次進行「遞迴呼叫」。
n=2-1,A B C

n=1-1,A B C
3~4~5:從副程式的頭到 if 做判斷 n 等不等於 1,此時 n=1 而往下執行。
6~7~8:輸出“將第1盤從A柱搬到C柱”。
12:輸出“將第2盤從A柱搬到B柱”。
13:再度進行「遞迴呼叫」。
n=2-1,C A B

n=1,C A B
3~4~5:從副程式的頭到 if 做判斷 n 等不等於 1,此時 n=1 而往下執行。
6~7~8:輸出“將第1盤從C柱搬到B柱”。
12:輸出“將第3盤從A柱搬到C柱” 。
13:進行「遞迴呼叫」。
n=3-1,B A C
n=2,B A C
3~4~5:從副程式的頭到 if 做判斷 n 等不等於 1,此時 n=2 所以不執行。
9~10:進入到 else 做處理。
11:進行「遞迴呼叫」。
n=2-1,B C A

n=1,B C A
3~4~5:從副程式的頭到 if 做判斷 n 等不等於 1,此時 n=1 而往下執行。
6~7~8:輸出“
將第1盤從B柱搬到A柱”。
12:輸出“將第2盤從B柱搬到C柱”。
13:進行「遞迴呼叫」。
n=2-1,A B C
n=1,A B C
3~4~5:從副程式的頭到 if 做判斷 n 等不等於 1,此時 n=1 而往下執行。
6~7~8:輸出“將第1盤從A柱搬到C柱”。
遞迴與副程式完全結束!

最後回到主程式:23~24~25。
結束。


所以 3 個盤的整體執行流程範例就是這樣,
總共是 7 次搬移;
如果說 4 個盤的話會要 15 次,
其公式是 2n-1

沒有留言:

張貼留言