1. 程式人生 > >通過二叉樹的中序和後序遍歷序列構造二叉樹(非遞迴)

通過二叉樹的中序和後序遍歷序列構造二叉樹(非遞迴)

題目:通過二叉樹的中序和後序遍歷序列構造二叉樹

同樣,使用分治法來實現是完全可以的,可是在LeetCode中執行這種方法的程式碼,總是會報錯:

Memory Limit Exceeded

 ,所以這裡還是用棧來實現二叉樹的構建。

與用先序和後序遍歷構造二叉樹的方法類似,但還是要做一些改變:



如果從後往前處理中序和後序的序列,則處理就為如下所示的情況:

Reverse_Post: 根—右子樹—左子樹
Reverse_In: 右子樹—根—左子樹


這樣處理方式和先序—中序就差不多了,只是將新增左孩子的情況,改為新增右孩子,反之依然。 實現程式碼如下所示:
TreeNode *buildTree_in_post(vector<int> &inorder, vector<int> &postorder)
{
    stack<TreeNode *> s;
    int len = (int) inorder.size();
    if(len == 0)
        return  NULL;
    int in_ptr, post_ptr;//分別用於對中序和後序處理
    in_ptr = post_ptr = len-1;//從序列最後一個元素往前進行處理
    TreeNode* root = new TreeNode(postorder[post_ptr]);//構造根結點,後序遍歷最後一個元素為根結點的值
    TreeNode* pCur = root;//用於儲存樹當前處理結點
    int flag = 0;//用於決定是否構造左結點
    post_ptr--;
    s.push(root);

    while(post_ptr > -1)//處理到pOstorder[0]
    {
        if(!s.empty() && s.top()->val == inorder[in_ptr])
        {
           pCur = s.top();
           s.pop();
           in_ptr--;
           flag = 1;
        }
        else
        {
            if(flag == 1)//構造左結點
            {
                pCur->left = new TreeNode(postorder[post_ptr]);
                pCur = pCur->left;
                s.push(pCur);
                post_ptr--;
                flag = 0;
            }
            else//構造右結點
            {
                pCur->right = new TreeNode(postorder[post_ptr]);
                pCur = pCur->right;
                s.push(pCur);
                post_ptr--;
            }
        }
    }
    return root;
}