設a, b, c是3個塔座:開始時,塔座a上有n個自上而下、由小到大地疊在一起圓盤,各圓盤從小到大編號爲1, 2, …, n,現要求將塔座a上的這一疊圓盤移到塔座b上,並仍按同樣順序疊置,移動圓盤時遵守以下移動規則:
規則1:每次只能移動1個圓盤;
規則2:不允許將較大的圓盤壓在較小的圓盤之上;
規則3:在滿足移動規則1和2的前提下,可將圓盤移至a, b, c中任一塔座上。
算法設計思路
由於移動規則爲大的在下,下的在上,所以可以採用捆綁的思想來移動圓盤。具體是:起始塔座爲a,目標塔座是b,所以首先借助b塔座,把前面n-1個圓盤移動到c塔座,剩下第n個圓盤則移動b塔座,最後再借助a塔座,把n-1個圓盤移動到b塔座上。
算法實現的僞代碼
說明:functionA爲自定義的函數名,input 1, input 2, …, input n爲functionA的輸入形參;在“輸入”中描述各輸入形參的含義;在“輸出”中描述functionA的輸出或作用效果;在S1~Sk中採用僞代碼描述語言簡要表達functionA的核心步驟。
算法functionA(input 1, input 2, …, input n)
輸入:起始塔座a,目標塔座b,中介塔座c,以及圓盤的個數。
輸出:圓盤實現從a塔座到塔座b的具體路徑。
S1:'A'→a; 'B'→b;'C'→c; n→n;
S2:void han(a,b,c,n)
S3:if n=1 then move(a,b)
S4:else then han(a,b,c,n-1)
S5:move(a,b)
S6:han(c,a,b,n-1)
實現代碼
說明:只粘貼functionA的Java或C++實現代碼即可,並對算法實現的關鍵性語句進行註釋。
public void han(char a,char c,char b,int n){
if(n==1){//邊界條件
move(a,b);//當n=1時,直接移到目標塔座即可。
}
else{
han(a,b,c,n-1);//採用捆綁的方法,把上面n-1個圓盤從a塔移動到c塔
move(a,b);//把剩下的最後一個圓盤移動到b塔座
han(c,a,b,n-1);//採用捆綁法,把c塔座上的n-1個圓盤移到b塔座
}
}
算法運行結果及計算時間複雜度分析
說明:通過計算迭代次數、基本運算語句的頻度,或利用遞推關係估算functionA的計算時間複雜度,要求給出具體的算法分析思路與過程,不能僅列出一個結果。
具體運算過程:
由遞推可算出:
T(n)=2T(n-1)+1;
T(n-1)=2T(n-2)+1;
.....
T(2)=2T(1)+1;
根據觀察可以發現,右邊式子中的T函數與下一式左邊的式子存在着2倍的關係,所以每個式子兩邊同時乘以2^(n-1),得:
T(n)=2T(n-1)+1;
2*T(n-1)=2*2T(n-2)+2*1;
.....
2^(n-1)*T(2)=2^(n-1)*2T(1)+2^(n-1)*1;
所有式子相加,可得:
T(n)=2^(n-1)*2T(1)+1*(1+2+2^2+……+2^(n-1))
=2^n+2^n-1
=2^(n+1)-1
所以O(n)=O(T(n))=O(O(1)+O(2^(n+1)-1))=O(2^(n+1)+1-1)=O(2^(n+1))=O(2^n).
運行結果:
該文爲原創,有什麼錯誤的地方,可以在評論區留言。