資料結構學習(C++)——遞迴【2】(4) (轉)
#include
#include
using namespace std;
class Needle
{
public:
Needle() { a.push_back(100); }//每一個柱子都有一個底座
void push(int n) { a.push_back(n); }
int top() { return a.back(); }
int pop() { int n = a.back(); a.pop_back(); return n; }
int movenum(int n) { int i = 1;while (a[i] > n) i++; return a.size() - i; }
int size() { return a.size(); }
int operator [] (int n) { return a[n]; }
private:
vector
};
void Hanoi(int n)
{
Needle needle[3], ns;//3個柱子,ns是轉換柱子時的儲存棧,借用了Needle的棧結構
int = 0, target, target_m = 2, disk, m = n;
for (int i = n; i > 0; i--) needle[0].push(i);//在A柱上放n個盤子
while (n)//問題規模為n,開始搬動
{
if (!m) { source = ns.pop(); target_m = ns.pop();
m = needle[source].movenum(ns.pop()); }//障礙盤子搬走後,回到原來的當前柱
if (m % 2) target = target_m; else target = 3 - source - target_m;//規律1的實現
if (needle[source].top() < needle[target].top())//當前柱頂端盤子可以搬動時,移動盤子
{
disk = needle[source].top();m--;
cout << disk << " move " << (char)(source + 0x41) << " to "<< (char)(target + 0x41) << endl;//顯示搬動過程
needle[target].push(needle[source].pop());//在目標柱上面放盤子
if (disk == n) { source = 1 - source; target_m = 2; m = --n; }規律3的實現
}
else//規律2的實現
{
ns.push(needle[source][needle[source].size() - m]);
ns.push(target_m); ns.push(source);
m = needle[target].movenum(needle[source].top());
target_m = 3 - source - target; source = target;
}
}
}
這個演算法實現比遞迴演算法複雜了很多(遞迴演算法在網上、書上隨便都可以找到),而且還慢很多,似乎是多餘的,然而,這是有現實意義的。我不知道現在還在搬64個盤子的僧人是怎麼搬的,不過我猜想一定不是先遞迴到1個盤子,然後再搬——等遞迴出來,估計鬍子一打把了(能不能在人世還兩說)。我們一定是馬上決定下一步怎麼搬,就如我上面寫的那樣,這才是人的正常思維,而用遞迴來思考,想出來怎麼搬的時候,黃瓜菜都涼了。正像我們做事的方法,雖然我今生今世完不成這項事業,但我一定要為後人完成我能完成的,而不是在那空想後人應該怎麼完成——如果達不到最終的結果,那也一定保證向正確的方向前進,而不是呆在原地空想。
由此看出,實際上和正常的做事步驟的差距還是很大的——我們的做事步驟如果直接用計算機來實現的話,其實並不能最優,原因就是,實際中的相關性在計算機中可能並不存在——比如人腦的逆推深度是有限的,而計算機要比人腦深很多,論記憶的準確性,計算機要比人腦強很多。這也導致了一個普通的員和一個資深的程式設計師寫的演算法的速度常常有天壤之別。因為,後者知道計算機喜歡怎麼思考。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-959496/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料結構學習(C++)——遞迴【2】(2) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(1) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(3) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【3】(2) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【1】 (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【3】(1) (轉)資料結構C++遞迴
- 資料結構學習(C++)——迴圈連結串列 (轉)資料結構C++
- 資料結構與演算法學習總結--遞迴資料結構演算法遞迴
- 資料結構學習(C++)——圖【4】(最短路徑) (轉)資料結構C++
- 資料結構-遞迴資料結構遞迴
- 資料結構學習筆記-遞迴求解森林高度資料結構筆記遞迴
- 資料結構學習(C++)——序言 (轉)資料結構C++
- 資料結構學習(C++)——二叉樹【2】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——圖【2】(DFS和BFS) (轉)資料結構C++
- 資料結構學習(C++)——圖(總結) (轉)資料結構C++
- 資料結構學習(C++)——樹(總結) (轉)資料結構C++
- 資料結構學習(C++)續——排序【2】插入排序 (轉)資料結構C++排序
- 資料結構學習(C++)——線性鏈式結構總結(代後記)【2】 (轉)資料結構C++
- 資料結構5_遞迴資料結構遞迴
- 資料結構學習(C++)——雙向連結串列 (轉)資料結構C++
- 資料結構學習(C++)——稀疏矩陣(十字連結串列【2】) (轉)資料結構C++矩陣
- 資料結構學習(c++)——二叉樹 (轉)資料結構C++二叉樹
- 基礎資料結構之遞迴資料結構遞迴
- 前端學習 資料結構與演算法 快速入門 系列 —— 遞迴前端資料結構演算法遞迴
- 【資料結構】二叉樹遍歷(遞迴+非遞迴)資料結構二叉樹遞迴
- 資料結構學習(C++)續——排序【3】交換排序 (轉)資料結構C++排序
- 資料結構學習(C++)——二叉樹【3】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——二叉樹【1】 (轉)資料結構C++二叉樹
- 資料結構和演算法:遞迴資料結構演算法遞迴
- 資料結構:歸併排序(非遞迴)資料結構排序遞迴
- 資料結構與演算法:遞迴資料結構演算法遞迴
- 關於樹型結構資料遞迴查詢,轉非遞迴查詢的實現遞迴
- 【資料結構】遞迴實現連結串列逆序資料結構遞迴
- 資料結構與演算法讀書筆記 - 004 -C++遞迴資料結構演算法筆記C++遞迴
- 資料結構學習(C++)——圖【3】(無向圖)(上) (轉)資料結構C++
- 資料結構學習(C++)——圖【3】(無向圖)(下) (轉)資料結構C++
- 資料結構學習(C++)——棧應用(表示式求值) (轉)資料結構C++
- 資料結構學習(C++)——圖【1】(基本儲存方法) (轉)資料結構C++