输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

该文章转载于:http://www.cnblogs.com/wdan2016/p/5988560.html

// test20.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>

using namespace std;


 struct TreeNode {
 int val;
 TreeNode *left;
 TreeNode *right;
 TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };

class Solution {
public:
    struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> in) {
        //先通过前序遍历找到跟节点
        //再通过跟节点把中序遍历的结果分为左子树tree_left和右子树tree_right
        //tree_left在前序遍历中的第一个节点就是跟节点的左孩子
        //tree_right在前序遍历中的第一个节点就是跟节点的右孩子
        if (pre.size() == 0) return NULL;
        /*if (pre.empty() || in.empty() || pre.size() != in.size())
            return NULL;*/
        TreeNode* root = new TreeNode(pre[0]); //前序遍历的第一个节点就是跟节点
    if (pre.size() == 1) return root;

        vector<int> in_left, in_right;//中序遍历中的左子树和右子树
        vector<int> pre_left, pre_right;//前序遍历中的左子树和右子树
        int num_left=0, num_right=0; //分别存储左子树和右子树的个数
        int cur = pre[0]; //存储谦虚遍历中的第一个值,根据这个值在将中序遍历分为左子树和右子树
    
        int pos = 0;//中序遍历中cur中的位置
        

        for (int i = 0;i < in.size();i++)  //计算中序遍历的左子树和右子树
        {
            if (in[i] == cur)
                pos = i;
        }
        for (int i = 0;i < in.size();i++)
        {
            if (i < pos)
            {
                in_left.push_back(in[i]);
                num_left++;
            }
                
            if (i > pos)
            {
                in_right.push_back(in[i]);
                num_right++;
            }
        }

        for (int i = 1;i < pre.size();i++) //计算先序遍历的左子树和右子树
        {
            if (num_left)
            {
                pre_left.push_back(pre[i]);
                --num_left;
            }
            else if (num_right)
            {
                pre_right.push_back(pre[i]);
                --num_right;
            }
            else
            {

            }
        }

        //if(!pre_left.empty()&&root!=NULL)
            root->left=reConstructBinaryTree(pre_left,in_left);
        //if(!pre_right.empty() && root != NULL)
            root->right = reConstructBinaryTree(pre_right,in_right);
            return root;//最后返回根节点,这点很重要,之前都是因为这个一直调试不通过

    }
    void preOrder(TreeNode* &T)
    {
        if (T == NULL) return;
        else
        {
            cout << T->val << "  ";
            preOrder(T->left);
            preOrder(T->right);
        }
    }

    void preCreate(TreeNode * &T)
    {
        int num;
        cin >> num;
        if (num == 0) return;
        else
        {
            T = new TreeNode(num);
            preCreate(T->left);
            preCreate(T->right);
        }
    }
};
int main()
{
    
    Solution so;
    TreeNode *T;
    vector<int> pre = { 1,2,4,7,3,5,6,8 };
    vector<int> in = { 4,7,2,1,5,3,8,6 };

    //vector<int> pre = {1,2};
    //vector<int> in = {2,1};
    //so.preCreate(T);
//  cout << "创建成功!" << endl;



    T = so.reConstructBinaryTree(pre,in);
    cout << "构建成功" << endl;

    cout << "前序遍历二叉树:" << endl;
    so.preOrder(T);
    
    
    cout << endl;
    return 0;
}