資料結構學習(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):String、遞迴、排序C++筆記遞迴排序
- 資料結構5_遞迴資料結構遞迴
- 基礎資料結構之遞迴資料結構遞迴
- 前端學習 資料結構與演算法 快速入門 系列 —— 遞迴前端資料結構演算法遞迴
- 資料結構和演算法:遞迴資料結構演算法遞迴
- 資料結構與演算法:遞迴資料結構演算法遞迴
- 資料結構:歸併排序(非遞迴)資料結構排序遞迴
- 資料結構與演算法讀書筆記 - 004 -C++遞迴資料結構演算法筆記C++遞迴
- js樹型結構資料簡易遞迴JS遞迴
- C++資料結構和pb資料結構的轉換C++資料結構
- 【C++】翻轉二叉樹(遞迴、非遞迴)C++二叉樹遞迴
- 實戰PHP資料結構基礎之遞迴PHP資料結構遞迴
- 實戰 PHP 資料結構基礎之遞迴PHP資料結構遞迴
- 資料結構學習資料結構
- Java資料結構與演算法--遞迴和回溯Java資料結構演算法遞迴
- 反轉連結串列系列題練習遞迴遞迴
- 通用-遞迴樹結構遞迴
- 資料結構學習之樹結構資料結構
- 資料結構與演算法——歸併排序: 陣列&連結串列&遞迴&非遞迴解法全家桶資料結構演算法排序陣列遞迴
- 資料結構與演算法(十一)——演算法-遞迴資料結構演算法遞迴
- 資料結構學習心得資料結構
- 資料結構-樹以及深度、廣度優先遍歷(遞迴和非遞迴,python實現)資料結構遞迴Python
- 資料結構學習--連結串列資料結構
- 資料結構學習總結--圖資料結構
- 資料結構——迴圈佇列PTA習題資料結構佇列
- 重學資料結構和演算法(三)之遞迴、二分、字串匹配資料結構演算法遞迴字串匹配
- ORACLE遞迴查詢(適用於ID,PARENTID結構資料表)Oracle遞迴
- 資料結構學習筆記資料結構筆記
- SpringBoot學習之資料結構Spring Boot資料結構
- Flutter學習之Route跳轉及資料傳遞Flutter
- 【Java資料結構與演算法筆記(二)】樹的四種遍歷方式(遞迴&非遞迴)Java資料結構演算法筆記遞迴
- c++基本資料結構C++資料結構
- 反轉連結串列(遞迴與棧)遞迴
- C++單連結串列遞迴遍歷操作C++遞迴
- 收藏資料結構學習網站資料結構學習網站
- 資料結構學習之佇列資料結構佇列