青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

tbwshc

tbw

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  95 Posts :: 8 Stories :: 3 Comments :: 0 Trackbacks

常用鏈接

留言簿(4)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

二叉樹(Binary Tree)的前序、中序和后續遍歷是算法和數據結構中的基本問題,基于遞歸的二叉樹遍歷算法更是遞歸的經典應用。

假設二叉樹結點定義如下:

  1. // C++ 
  2. struct Node { 
  3.     int value; 
  4.     Node *left; 
  5.     Node *right; 

中序遞歸遍歷算法:

  1. // C++ 
  2. void inorder_traverse(Node *node) { 
  3.     if (NULL != node->left) { 
  4.         inorder_traverse(node->left); 
  5.     } 
  6.     do_something(node); 
  7.     if (NULL != node->right) { 
  8.         inorder_traverse(node->right); 
  9.     } 

前序和后序遍歷算法類似。

但是,僅有遍歷算法是不夠的,在許多應用中,我們還需要對遍歷本身進行抽象。假如有一個求和的函數sum,我們希望它能應用于鏈表,數組,二叉樹等等不同的數據結構。這時,我們可以抽象出迭代器(Iterator)的概念,通過迭代器把算法和數據結構解耦了,使得通用算法能應用于不同類型的數據結構。我們可以把sum函數定義為:

  1. int sum(Iterator it) 

鏈表作為一種線性結構,它的迭代器實現非常簡單和直觀,而二叉樹的迭代器實現則不那么容易,我們不能直接將遞歸遍歷轉換為迭代器。究其原因,這是因為二叉 樹遞歸遍歷過程是編譯器在調用棧上自動進行的,程序員對這個過程缺乏足夠的tb控制。既然如此,那么我們如果可以自己來控制整個調用棧的進棧和出棧不是就達到 控制的目的了嗎?我們先來看看二叉樹遍歷的非遞歸算法:

  1. // C++ 
  2. void inorder_traverse_nonrecursive(Node *node) { 
  3.     Stack stack; 
  4.     do { 
  5.         // node代表當前準備處理的子樹,層層向下把左孩子壓棧,對應遞歸算法的左子樹遞歸 
  6.         while (NULL != node) { 
  7.             stack.push(node); 
  8.             node = node->left; 
  9.         } 
  10.         do { 
  11.             Node *top = stack.top(); 
  12.             stack.pop(); //彈出棧頂,對應遞歸算法的函數返回 
  13.             do_something(top); 
  14.             if (NULL != top->right) { 
  15.                 node = top->right; //將當前子樹置為剛剛遍歷過的結點的右孩子,對應遞歸算法的右子樹遞歸 
  16.                 break
  17.             } 
  18.         } 
  19.         while (!stack.empty()); 
  20.     } 
  21.     while (!stack.empty()); 

通過基于棧的非遞歸算法我們獲得了對于遍歷過程的控制,下面我們考慮如何將其封裝為迭代器呢? 這里關鍵在于理解遍歷的過程是由棧的狀態來表示的,所以顯然迭代器內部應該包含一個棧結構,每次迭代的過程就是對棧的操作。假設tbw迭代器的接口為:

  1. // C++ 
  2. class Iterator { 
  3.     public
  4.         virtual Node* next() = 0; 
  5. }; 

下面是一個二叉樹中序遍歷迭代器的實現:

  1. //C++ 
  2. class InorderIterator : public Iterator { 
  3.     public
  4.         InorderIterator(Node *node) { 
  5.             Node *current = node; 
  6.             while (NULL != current) { 
  7.                 mStack.push(current); 
  8.                 current = current->left; 
  9.             } 
  10.         } 
  11.         virtual Node* next() { 
  12.             if (mStack.empty()) { 
  13.                 return NULL; 
  14.             } 
  15.             Node *top = mStack.top(); 
  16.             mStack.pop(); 
  17.             if (NULL != top->right) { 
  18.                 Node *current = top->right; 
  19.                 while (NULL != current) { 
  20.                     mStack.push(current); 
  21.                     current = current->left; 
  22.                 } 
  23.             } 
  24.             return top; 
  25.          } 
  26.     private
  27.         std::stack<Node*> mStack; 
  28. }; 

下面我們再來考察一下這個迭代器實現的時間和空間復雜度。很顯然,由于棧中最多需要保存所有的結點,所以其空間復雜度是O(n)的。那么時間復雜度 呢?一次next()調用也最多會進行n次棧操作,而整個遍歷過程需要調用n次next(),那么是不是整個迭代器的時間復雜度就是O(n^2)呢?答案 是否定的!因為每個結點只會進棧和出棧一次,所以整個迭代過程的時間復雜度依然為O(n)。其實,這和遞歸遍歷的時空復雜度完全一樣。

除了上面顯式利用棧控制代碼執行順序外,在支持yield語義的語言(C#, Python等)中,還有更為直接的做法。下面基于yield的二叉樹中序遍歷的Python實現:

  1. // Python 
  2. def inorder(t): 
  3.     if t: 
  4.         for x in inorder(t.left): 
  5.             yield x 
  6.         yield t.label 
  7.         for x in inorder(t.right): 
  8.             yield x 

yield與return區別的一種通俗解釋是yield返回時系統會保留函數調用的狀態,下次該函數被調用時會接著從上次的執行點繼續執行,這是一種與 棧語義所完全不同的流程控制語義。我們知道Python的解釋器是C寫的,但是C并不支持yield語義,那么解釋器是如何做到對yield的支持的呢? 有了上面把遞歸遍歷變換為迭代遍歷的經驗,相信你已經猜到Python解釋器一定是對yield代碼進行了某種變換。如果你已經能夠實現遞歸變非遞歸,不 妨嘗試一下能否寫一段編譯程序將yield代碼變換為非yield代碼。

posted on 2013-07-17 17:09 tbwshc 閱讀(163) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产成人久久综合| 欧美刺激性大交免费视频| 亚洲另类自拍| 亚洲社区在线观看| 亚洲欧美激情四射在线日| 久久女同精品一区二区| 91久久精品国产| 欧美一区二区三区成人| 欧美激情 亚洲a∨综合| 国产精品一区二区三区观看| 亚洲国产精品毛片| 亚洲欧洲偷拍精品| 美女久久网站| 国产精品国码视频| 欧美岛国在线观看| 亚洲永久网站| 欧美日韩极品在线观看一区| 国产一区日韩欧美| 午夜激情久久久| 日韩视频在线一区| 欧美刺激性大交免费视频| 国产自产精品| 久久精品国产欧美亚洲人人爽| 免费毛片一区二区三区久久久| 亚洲男人影院| 一区二区三区四区蜜桃| 久久久久www| 久久激情婷婷| 国产视频一区二区在线观看| 久久久亚洲一区| 欧美精品www| 欧美一区在线直播| 欧美日韩mp4| 99精品视频一区| 亚洲巨乳在线| 欧美日韩中文在线观看| 午夜精品久久久久影视| 亚洲免费在线观看| 合欧美一区二区三区| 日韩亚洲精品视频| 9i看片成人免费高清| 国产精品mv在线观看| 夜夜嗨av一区二区三区中文字幕| 日韩亚洲精品在线| 国内精品久久久久影院 日本资源| 久久久亚洲成人| 欧美女激情福利| 久久成人精品视频| 欧美高清在线精品一区| 欧美亚洲一区三区| 久久夜色精品| 亚洲男人天堂2024| 国产精品呻吟| 久久国内精品视频| 欧美成人高清视频| 亚洲免费观看高清完整版在线观看熊| 亚洲国产va精品久久久不卡综合| 亚洲三级性片| 国内久久婷婷综合| 另类综合日韩欧美亚洲| 久久激情五月丁香伊人| 亚洲精品久久久一区二区三区| 欧美一区二区三区在| 欧美日韩一区视频| 欧美日韩午夜剧场| 一区二区日韩欧美| 性欧美暴力猛交另类hd| 午夜精品视频一区| 国产视频自拍一区| 午夜精品99久久免费| 久久亚洲一区二区| 国产欧美日韩不卡| 好看的日韩视频| 一区二区三区四区精品| 国产一区二区成人久久免费影院| 麻豆国产va免费精品高清在线| 亚洲片区在线| 欧美国产综合视频| 夜夜夜久久久| 亚洲理论电影网| 久久人91精品久久久久久不卡| 国产一区二区三区在线观看视频 | 久久久五月天| 亚洲色无码播放| 欧美一级片在线播放| 亚洲综合电影一区二区三区| 亚洲激情影视| 亚洲欧美日韩一区二区在线| 亚洲视频观看| 久久久久久午夜| 欧美+日本+国产+在线a∨观看| 欧美国产日韩在线观看| 亚洲国产小视频| 亚洲一区二区高清| 欧美日韩在线电影| 久久天堂成人| 亚洲午夜精品久久久久久浪潮| 欧美怡红院视频| 久久国产日韩| 99国产精品| 欧美午夜久久久| 免费看精品久久片| 亚洲福利视频二区| 亚洲精品国产精品国自产观看| 香蕉久久夜色精品国产使用方法| 欧美精品久久99| 国产丝袜美腿一区二区三区| 一区在线免费观看| 国产精品二区三区四区| 在线观看视频免费一区二区三区| 亚洲欧美美女| 国产精品日韩久久久| 亚洲精品四区| 国产在线欧美| 久久字幕精品一区| 另类成人小视频在线| 91久久国产综合久久蜜月精品| 性欧美大战久久久久久久久| 日韩一级黄色片| 国产精品久久久久久久久久免费 | 欧美一区午夜精品| 国产精品高潮久久| 国产欧美综合在线| 国产精品亚洲аv天堂网| 另类av导航| 欧美日韩国产一区二区三区| 欧美日韩欧美一区二区| 久久免费视频在线观看| 久久蜜桃香蕉精品一区二区三区| 亚洲伦理中文字幕| 日韩亚洲在线| 亚洲欧美成人一区二区三区| 国产精品mm| 久久精品1区| 正在播放亚洲一区| 亚洲一区在线播放| 欧美午夜电影在线观看| 亚洲一区在线播放| 欧美一区二区三区久久精品茉莉花| 韩国三级电影久久久久久| 久久精品视频在线看| 欧美国产乱视频| 夜久久久久久| 国产欧美一区二区精品性| 欧美一区免费视频| 欧美激情小视频| 久久精品国产亚洲a| 亚洲国产一区视频| 国产精品自拍小视频| 久久久爽爽爽美女图片| 亚洲精品女人| 久久免费视频观看| 国产一区二区三区日韩欧美| 亚洲欧美制服中文字幕| 欧美激情女人20p| 久久国产高清| 好吊日精品视频| 久久成人人人人精品欧| 日韩性生活视频| 欧美国产成人精品| 尤物九九久久国产精品的特点| 欧美在线视频播放| 欧美www视频| 亚洲网站视频| 欧美视频免费| 日韩亚洲视频在线| 亚洲日本久久| 欧美视频在线播放| 久久本道综合色狠狠五月| 欧美va亚洲va日韩∨a综合色| 亚洲欧美国产毛片在线| 欧美承认网站| 亚洲欧美激情诱惑| 亚洲欧美影院| 在线免费精品视频| 美女在线一区二区| 久久亚洲一区二区| 亚洲线精品一区二区三区八戒| 99爱精品视频| 国产精品欧美在线| 国产精品a级| 久久久成人网| 欧美日韩成人一区二区三区| 午夜精品国产更新| 国产婷婷色综合av蜜臀av| 亚洲一区二区三区午夜| 你懂的视频一区二区| 午夜宅男欧美| 欧美大片一区二区| 国内精品福利| 久久综合一区二区| 久久av资源网| 亚洲国产成人久久综合| 99国产精品久久| 伊人狠狠色j香婷婷综合| 国语自产精品视频在线看一大j8 | 午夜欧美不卡精品aaaaa| 一区二区高清在线| 一二三区精品| 激情校园亚洲|