1. 程式人生 > >漢諾塔層數大於10時輸出不正常的分析及時間複雜度

漢諾塔層數大於10時輸出不正常的分析及時間複雜度

使用遞迴方式解決漢諾塔問題,具體思路就不詳細敘述了,程式碼如下:

#include <iostream>

using namespace std;

int i;

void moveDisk(int diskNum, char from, char to, char aux)
{
	if(diskNum == 1){
		cout << "step" << ++i << ": ";
		cout << "Move disk1 from " << from
		<< " to " << to << "\n";
	}
	else{
		moveDisk(diskNum - 1, from, aux, to);
		
		cout << "step" << ++i << ": ";
		cout << "Move disk" << diskNum
		<< " from " << from << " to " << to << "\n";
		
		
		moveDisk(diskNum - 1, aux, to, from);
	}
}

int main()
{
	int init;
	cin >> init;
	
	moveDisk(init, 'A', 'C', 'B');
	
	return 0;
}

自己在執行時,發現了這樣的問題,當輸入層數init大於等於10時,命令列輸出中沒有大於等於10的盤號!一開始以為是實現思路有問題,但反覆思考幾遍並沒有發現問題,然後我認為可能編譯器對巢狀層數有要求,當層數太大時,超過了規定巢狀層數而導致輸出錯誤,按照這一思路查詢相關資訊,發現應該不是這個原因,編譯器對巢狀層數一般沒有要求,可能出現錯誤的情況是巢狀層數太深導致堆疊溢位,而10層的漢諾塔求解是不可能讓堆疊溢位的。

後來通過給每行輸出加上步驟號(本來沒有步驟號),發現原來命令列儲存的行數是有限制的,大於10的盤號被頂上去了未能顯示出來。。。

最後分析一下使用遞迴的方法解決漢諾塔問題的時間複雜度:

令盤數為n,執行次數為f(n),

當n=1時,f(1)=1;

當n=2時,f(2)=2*f(1)+1=3;

當n=3時,f(3)=2*f(2)+1=7;

.........

當n=n時,f(n)=2*f(n-1)+1;

由上面的公式變形可得f(n)+1=2[f(n-1)+1],則f(n)+1=2^2*[f(n-2)+1]=...=2^(n-1)*[f(1)+1]=2^n,

則f(n)=2^n-1,按照O階的寫法,複雜度為O(2^n)。