1. 程式人生 > >二叉樹的後序遍歷(leetcode 145)

二叉樹的後序遍歷(leetcode 145)

寫在前面

關於二叉樹的後序遍歷,我們通常要說的是它的非遞迴寫法,這一點,網上有很多寫法,大概看了一下,基於先前訪問結點的演算法基本屬於主流思想,但大家的寫法似乎都不太簡潔,有各種各樣的問題,這裡寫一種簡單易懂的寫法,供參考。

思路分析

1)其實除了層序遍歷外,三種方式的遍歷都可以看作是遞迴思想的延續,其中最難的要數後序遍歷,因為右子樹的訪問狀態是一個較難處理的點。我們觀察發現,左子樹訪問完成後,下一步是訪問右子樹,這個時候有幾種情況:1.右子樹為空 ,這個時候我們直接訪問根結點;2 右子樹已經訪問過了,這個時候的情況與1類似,我們直接訪問根結點;3 右子樹不為空且未被訪問過,這個時候我們就訪問右子樹,並遞迴處理。
2)標準庫設施。非遞迴的樹的遍歷幾乎都會用到棧(層序遍歷除外),後序遍歷也不例外。本題中,我們思路1,2,3的正確性也依賴於棧結構。我們訪問過的元素必定是棧頂元素,這一點由棧的特性保證(思考整個的後序遍歷過程),此外,我們有一個額外的結點來標記已訪問過的元素,與棧頂元素作比較。

程式碼實現

// 我們用vector儲存遍歷過的元素 並返回結果

vector<int> postOrder(Node* root) {
    stack<Node*> s;
    vector<int> retVec;
    Node* current = root;
    Node* pre = nullptr;
    while(!s.empty()||current){
        while(current) {
        s.push(current);
        current = current->left;
        }
        auto
top = s.top(); if(top->right==nullptr||top->right==pre) { pre = top; retVec.push_back(top->val); current = nullptr; s.pop(); } else { current = top->right; } } return retVec; }

小結

在某位同學的部落格上看到一個觀點,說要追求程式碼的極度簡潔,我認同簡潔的觀點,但我認為,可讀性仍然是第一位,其次是複雜度,過度追求簡潔並不可取。