1. 程式人生 > >72 中序遍歷和後序遍歷樹構造二叉樹

72 中序遍歷和後序遍歷樹構造二叉樹

實的 dong scrip size turn -c -h red 左右子樹

原題網址:https://www.lintcode.com/problem/construct-binary-tree-from-inorder-and-postorder-traversal/description

描述

根據中序遍歷和後序遍歷樹構造二叉樹

你可以假設樹中不存在相同數值的節點

您在真實的面試中是否遇到過這個題?

樣例

給出樹的中序遍歷: [1,2,3] 和後序遍歷: [1,3,2]

返回如下的樹:

2

/ \

1 3

標簽 二叉樹 思路:要建立二叉樹,首先要建立根節點,其次才是建立左右孩子並掛載。PS:建立鏈表是先確定前驅節點,再掛載。

1.已知中序遍歷和後序遍歷,如何確定根節點?我們知道,後序遍歷是左右根,所以後序遍歷的最後一個節點是當前樹的根節點。

2.接下來是左右孩子,要借助中序遍歷。中序遍歷裏,根節點左側是左子樹,右側是右子樹。先定位根節點(前提是樹中不存在相同數值的節點),則左右子樹的數量就可以確定了。根據左右子樹的數量可以確定左右子樹的中序遍歷和後序遍歷,遞歸構建並掛載左右子樹即可。

3.當中序遍歷的起始索引大於結束索引時,說明二叉樹已經建立完畢。

AC代碼:

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 
*/ class Solution { public: /** * @param inorder: A list of integers that inorder traversal of a tree * @param postorder: A list of integers that postorder traversal of a tree * @return: Root of a tree */ TreeNode * buildTree(vector<int> &inorder, vector<int> &postorder) {
// write your code here int a=inorder.size(); int b=postorder.size(); if (a!=b||a==0||b==0) { return NULL; } return Build(inorder,postorder,0,a-1,0,b-1); } TreeNode * Build(vector<int> &inorder, vector<int> &postorder,int inst,int ined,int post,int poed) { if (inst>ined) { return NULL; } int i=inst; while(i<=ined&&inorder[i]!=postorder[poed])//找到中序遍歷根節點所在位置; { i++; } TreeNode * root=new TreeNode(postorder[poed]);//根節點; root->left=Build(inorder,postorder,inst,i-1,post,post+i-1-inst);//左孩子; root->right=Build(inorder,postorder,i+1,ined,post+i-inst,poed-1);//右孩子; return root; } };

其他方法:

Lintcode---中序遍歷和後序遍歷樹構造二叉樹

LintCode2016年8月8日算法比賽----中序遍歷和後序遍歷構造二叉樹

根據中序遍歷和後序遍歷樹構造二叉樹

PS:最開始的遞歸函數只設置了起始和終止兩個索引,因為我只註意到了左右子樹在中序遍歷和後序遍歷中長度相等,但沒註意到左右子樹的起始、終止索引在中序遍歷與後序遍歷中是不一樣的ORZ……也不知道當時怎麽想的,明明畫了圖對照……

Mark一下曾經的失敗代碼:

TreeNode * build(vector<int> &inorder, vector<int> &postorder,int st,int ed)
{
    if (st>ed)
    {
        return NULL;
    }
    int i=st;
    while(i<=ed&&inorder[i]!=postorder[ed])//找到中序遍歷根節點所在位置;
    {
        i++;
    }
    TreeNode * root=new TreeNode(postorder[ed]);//根節點;
    root->left=build(inorder,postorder,st,i-1);//左孩子;
    root->right=build(inorder,postorder,i,ed-1);//右孩子,註意是從i開始,不是i+1;
    return root;
}

72 中序遍歷和後序遍歷樹構造二叉樹