1. 程式人生 > >遞迴的應用:求解漢諾塔問題

遞迴的應用:求解漢諾塔問題

  • 題目描述:漢諾塔問題是一個經典的問題,其來源據說在19世紀末歐洲的商店中出售一種智力玩具,在一塊銅板上有三根杆,最左邊的杆自上而下、由小到大順序串著64個圓盤構成的塔,遊戲的目的是將左邊A杆上的圓盤藉助最右邊的C杆,全部移動到中間的B杆上,條件是一次僅能移動一個盤,且不允許大盤放在小盤上面,問最少需要移動多少次。
  • 解法描述:我們可知限制條件為:一次只能移動一個盤,且不允許大盤放在小盤上面。解法為:首先我們設要解決的漢諾塔有n個圓盤,對A杆上的全部n個圓盤從小到大順序編號,最小的為1號,依次遞增,最大的圓盤編號為n。
    • 第一步:假設此時A杆上只有一個圓盤,即漢諾塔只有一層,那麼將其移動到B杆上即可。

    • 第二步:對於有n(n>1)個圓盤的漢諾塔,將n個圓盤分為兩個部分,上面n-1個圓盤為一個部分,下面編號為n的一個圓盤為另一部分。

    • 第三步:將“上面n-1個圓盤“看成一個整體,為了解決這n個圓盤的漢諾塔可以進行下列操作:

      • 將A杆上的n-1個圓盤藉助B杆移到C杆上,此時設C杆上有n個盤子(n = n - 1);
      • 將A杆上剩下的編號為n的盤子移動到B杆上;
      • 將C杆上的n-1個盤子藉助A杆移到B杆上。
      • 在將n-1個圓盤從C杆上移動到B杆上和原問題具有具有相同的特徵屬性,只是問題的規模小於原問題,故我們可以使用遞迴的方法來求解。
    • 下面就以四個盤子為例,來解釋盤子的移動過程: 初始狀態的漢羅塔:

第一次藉助B杆將A杆上的n-1個盤子移動到C杆上並把A杆上的最後一個盤子移動打B杆上後的結果: 在這裡插入圖片描述 再借助B杆將C杆上的n-1個盤子移動到A杆並將C杆上的最後一個盤子移動到B杆上後的結果: 在這裡插入圖片描述

遞迴對A杆、B杆和C杆上的盤子的移動操作直至最後一個盤子移動到B杆上結束。 在這裡插入圖片描述

最後的結果: 在這裡插入圖片描述

程式設計實現

#include<iostream>
using namespace std;
void Hanoi(int n, char a, char b, char c, int &count)
{
	if(n == 1)
	{
		count++;//移動A杆上的最後一個盤子到B杆
	}
	else
	{
		Hanoi(n - 1, a, b ,c, count);            //A 杆藉助B杆移動n-1個盤子到C杆
		count++;                                 //移動A杆上的最後一個盤子到B杆
                Hanoi(n - 1, c, b ,a, count);           //C杆藉助B杆將n-1個盤子移動到A杆
	}
}
int main()
{
	int count,n;
	cout << "please input the count:";
	cin >> n;
	count = 0;
	Hanoi(n, 'A', 'B', 'C', count);
	cout << "total = " << count << endl;
}

測試結果: 在這裡插入圖片描述