#編程基礎#算法——Hanoi塔問題

歡迎前往個人博客 駑馬點滴 和視頻空間 嗶哩嗶哩-《挨踢日志》

【問題】


a,b,c是三個塔座。開始時,在a上共有n個圓盤,自上而下,圓盤由小到大。編號分別為1,2,...,n. 現在要通過b塔把圓盤從a塔移動到c塔.試寫出移動過程hanoi(n,a,b,c).

【解答】


建模

我們記錄每一次轉移為 x -> y 其中 x~=y, x, y從{a, b, c}中取值
那么問題就是要給出一些列的轉移的有序集合,使得按照集合中的步驟,能夠將n個盤從a移動到c

這里有3個塔: a、b、c,由于a是起始塔,而c是目標塔,b就是輔助塔,于是需要引入3個變量:起始塔、目標塔、輔助塔
同時還有一個由圓盤組成的堆的概念。有一個變量n用于描述這個堆的大小,因為我們不希望打亂堆的從上到下的圓盤是由小到大的布局,所以,n就唯一決定了這個堆的特性。
顯然,我們接觸到n這個變量,自然希望使用數學歸納法來解決這樣的問題,于是問題,應當考慮將n的情形轉化為n-1的情形,從而通過遞歸完成我們的解決方案。

首先我們假定解決方案是一個關于 n 和 起始塔、輔助塔、目標塔 的函數 hanoi(n, 起始塔, 輔助塔, 目標塔)
表示n個圓盤,從起始塔,通過輔助塔移動到目標塔的解決方案。

那么我們需要求解的問題就是:hanoi(n, a, b, c)

而 hanoi(n, a, b, c)的解決方案是一個步驟方案,于是我們又可以將這個過程視為3大步驟:

  1. 先將a上面的n-1個盤組成的堆從a,借助輔助塔c,轉移到b的解決方案hanoi(n-1, a, c, b)
  2. 將第n個盤移動到c: hanoi(1, a, b, c)
  3. 再將b上面的n-1個盤組成的堆從b,借助輔助塔a,轉移到c的解決方案hanoi(n-1, b, a, c)

于是遞歸算法如下:

void LankeHelper::hanoi(int n, char a, char b, char c){
    if(n==1)
    {
        cout<<a<<"->"<<c<<"\n";
    }
    else {
        hanoi(n-1,a,c,b); 
        hanoi(1, a, b, c);
        hanoi(n-1,b,a,c);
     }
}
int _tmain(int argc, _TCHAR* argv[]){ 
    LankeHelper lh;
    lh.hanoi(2,'a','b','c');
    system("pause");
    return 0;
}

歡迎前往個人博客 駑馬點滴 和視頻空間 嗶哩嗶哩-《挨踢日志》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 難得掃地 我清理了房間 是這半個月的垃圾 像倒掉壞心情 放一首歌 不需是我喜歡的 聲響 于是整個早晨都那么明亮 我...
    后生執筆閱讀 223評論 5 3
  • A1標準: 1.要是自己過去的經歷; 2.要聚焦在一個事件; 3.要具體,要是一個生動形象的描述,不要泛泛而...
    涂涂悅讀閱讀 143評論 2 1