剑指offer编程-重建二叉树

题目描述

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

思路:

1.根据前序第一个为根节点;

2.然后在中序序列中找到根节点,根节点左侧为它的左子树,根节点右侧为它的右子树;

3.递归对左子树重复步骤1,步骤2。注意递归终止条件:只有一个节点。

#include<iostream>
#include<vector>
//#include <cstdlib>
using namespace std;


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


class Solution {
public:
    TreeNode* reConstructCore(int *pre_start, int *pre_end, int *vin_start, int *vin_end){
        int root_value = *pre_start;
        TreeNode* root = new TreeNode(root_value);
        root->val = root_value;
        root->left = nullptr;
        root->right = nullptr;
        if (pre_start == pre_end){
            if (vin_start == vin_end)
                return root;
            else
                throw std::exception("Invalid Input");
        }
        else{
            int leftnum = 0;
            while (*(vin_start + leftnum) != root_value)
                leftnum++;
            if (leftnum > 0)
                root->left = reConstructCore(pre_start + 1, pre_start + leftnum , vin_start, vin_start + leftnum - 1);
            if (vin_end-vin_start>leftnum)
                root->right = reConstructCore(pre_start + leftnum + 1, pre_end, vin_start + leftnum + 1, vin_end);
        }
        return root;
    }
    TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
        int *pre_start = &pre[0];
        int *pre_end = &pre[pre.size()-1];
        int *vin_start = &vin[0];
        int *vin_end = &vin[vin.size() - 1];
        return reConstructCore(pre_start, pre_end, vin_start, vin_end);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    int a[] = { 1, 2, 4, 7, 3, 5, 6, 8, 4,7,2,1,5,3,8,6};
    vector<int> pre(a, a + 8);
    vector<int> vin(a+8, a + 16);
    Solution S;
    TreeNode *root;
    root = S.reConstructBinaryTree(pre, vin);

    cout << "按任意键继续……";
    cin.clear();
    cin.sync();
    cin.get();
    return 0;
}

测试用例:

1.普通二叉树(完全二叉树,不完全二叉树)。

2.特殊二叉树(只有左子树,只有右子树,只有一个节点的二叉树)。

3.特殊输入(空指针,前序遍历和中序遍历不匹配)。

编程,vector:

赋值方式;

指向vector数组的指针:即定义一个整形指针指向vector数组第一个元素的位置。不能指向vector数组名。

 

posted @ 2017-08-25 16:00  usj  阅读(98)  评论(0编辑  收藏  举报