二叉樹非遞迴尾碼遍曆

來源:互聯網
上載者:User

標籤:二叉樹   遞迴   遍曆   棧   演算法   

二叉樹的遍曆方法可分為深度優先和廣度優先兩種,其中深度優先遍曆適合使用棧來輔助實現,廣度優先則使用隊列,因為棧的先進後出和隊列的先進先出特點正好符合遍曆順序的要求。深度優先遍曆一般又分為前序走訪,中序遍曆,後序遍曆,對於一顆樹來說,前序、中序、後序針對的都是它的根節點,其中前序走訪訪問順序是:根節點-->左節點-->右節點,中序遍曆訪問順序是:左節點-->根節點-->右節點,後續遍曆訪問順序是:左節點-->右節點-->根節點。二叉樹的結構是遞迴的,因此非常適合使用遞迴的方法來完成遍曆,而且代碼很容易編寫,但是如果樹的深度很大,遞迴方法導致函數調用棧太深,而作業系統線程中棧的大小是有限的,函數調用又有一定的開銷,因此有時候需要使用非遞迴的方式來遍曆。


在非遞迴前序走訪時,從根節點向左走,每遇到一個節點,就訪問它,然後將該節點進棧,直到再沒有左節點。這時候將棧頂節點彈出,如果該棧頂節點沒有右節點,則表示以這個節點為根的樹已經訪問完畢,於是繼續彈出棧頂節點進行同樣的訪問操作,如果該棧頂節點有右節點,則將其右節點進棧,回到迴圈的開始處,對以這個右節點為根的子樹進行遍曆。中序遍曆方法很類似,區別只在於向左走時不是每遇到一個節點就訪問它,而是在再沒有左節點時,彈出棧頂節點,然後才訪問這個節點,之後對右節點進行和前序走訪一樣的操作。後序遍曆在向左走時和中序遍曆一樣,遇到一個節點時先不訪問它,而是直接進棧,特別要注意的是直到再沒有左節點時後序遍曆不能像中序遍曆那樣彈出棧頂元素。由於是後序遍曆,這個棧頂節點需要在它的右子樹節點全部被訪問之後才能被訪問,所以這時候需要先遍曆它的右子樹,遍曆子樹這個過程中也要用到棧,等到右子樹遍曆完成,棧頂元素又變成了剛才那個棧頂節點,這時候就可以彈出棧頂元素並訪問該節點,對於以該節點為根的二叉樹來說,這個順序符合後序遍曆中根節點是最後一個被訪問節點的定義。


從上面對後序遍曆的描述中可以知道,向左走時再沒有左節點時,我們就開始考查棧頂節點,要對它的右子樹進行遍曆,而同樣的,在其右子樹被訪問完畢時,棧頂節點還是剛才那個節點,這時候我們就要通過某種手段把這兩個狀態進行區分,要不然可能又要對這個棧頂節點的右子樹進行遍曆了,沒完沒了的。我們可以通過記下最後一個被訪問節點的指標,然後每次在考查棧頂節點時,看看最後被訪問的節點是不是它的右節點,如果不是那麼就處理右子樹,如果是則表明其右子樹已經遍曆完成,這時候可以彈出這個棧頂節點並訪問它。所以對於後序遍曆,可以寫出如下代碼:


vector<int> postorderTraversal(TreeNode* root)

{       
        vector<int> v_ret;
        if(!root) return v_ret;
         
        TreeNode* lastVisit = NULL;
         
        stack<TreeNode*> S;
         
        S.push(root);
        TreeNode* pNode = S.top();
         
        while(!S.empty())
        {
            if(pNode)
            {
               while(pNode->left)
               {
                   S.push(pNode->left);
                   pNode = pNode->left;
               }
            }
             
            pNode = S.top();
             
            if(pNode->right)
            {
                if(lastVisit != pNode->right)  
                {
                    S.push(pNode->right);
                    pNode = pNode->right;
                }
                else
                {
                    v_ret.push_back(pNode->val);
                    lastVisit = pNode;
                    pNode = NULL;
                    S.pop();
                }
            }
            else
            {
                v_ret.push_back(pNode->val);
                lastVisit = pNode;
                pNode = NULL; 
                S.pop();
            }
        }
         
        return v_ret;
}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

二叉樹非遞迴尾碼遍曆

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.