剑指offer 4 :重建二叉树

重建二叉树:

#include <iostream>
#include <vector>

//重建二叉树
using namespace std;
struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;

    TreeNode(int x)
        : val(x), left(NULL), right(NULL)
    {

    }

    static void PreOrder(TreeNode *root) {
        if (root == NULL) {
            return;
        }
        cout << root->val;
        PreOrder(root->left);
        PreOrder(root->right);//递归前序打印
    }

    static void InOrder(TreeNode *root) {
        if (root == NULL) {
            return;
        }
        InOrder(root->left);
        cout << root->val;//递归中序打印
        InOrder(root->right);
    }
};




class solution
{
public:
    struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> in) {
        if (pre.size() != in.size()) {//前序遍历和中序遍历长度应该相同
            return NULL;

        }

        int size = pre.size();
        if (size == 0) {
            return NULL;
        }//长度不能为空

        int length = pre.size();

        int value = pre[0]; //前序遍历的第一个节点是根节点
        TreeNode *root = new TreeNode(value);

        int rootIndex = 0;
        for (rootIndex = 0; rootIndex < length; rootIndex++) {
            if (in[rootIndex] == value) {  //在中序遍历中找到根的位置
                cout << "find" << endl;
                break;
            }
        }

        if (rootIndex >= length) {
            cout << "find" << endl;
            return NULL;
        }

        //确定左右子数的长度
        int leftLength = rootIndex;
        int rightLength = length - 1 - rootIndex;

        vector <int> preLeft(leftLength), inLeft(leftLength);
        vector <int> preRight(rightLength), inRight(rightLength);

        for (int i = 0; i < length; i++) {
            if (i < rootIndex) {
                //前序遍历的第一个是根节点,根后面的(leftLength = rootLength) -1 个节点
                //是左子树,因此是i+1
                preLeft[i] = pre[i+1];
                //中序遍历前(leftLength = rootLength - 1个节点是左子树,第rootIndex
                //个节点是根
                inLeft[i] = in[i];
            }

            else if ( i > rootIndex) {
                //前序遍历根后面rootIndex-1个节点是右子树
                preRight[i - rootIndex - 1] = pre[i];
                //中序遍历根前面rootIndex-1个节点是左子树,根后面是右子树
                inRight[i - rootIndex - 1] = in[i];
            }
        }

        for (int i = 0; i < leftLength; i++) {
            cout << preLeft[i] << "and" << inLeft[i]  << endl;

        }
        cout << endl;

        for (int i = 0; i < rightLength; i++) {
            cout << preRight[i] << "and" << inRight[i] << endl;
        }
        cout << endl;

        root->left = reConstructBinaryTree(preLeft, inLeft);
        root->right = reConstructBinaryTree(preRight, inRight);//递归重建

        return root;
    }
};





int main()
{
    int pre[] = {1,2,4,7,3,5,6,8};
    int in[] ={4,7,2,1,5,3,8,6};
    vector<int> preOrder(pre, pre + 8);
    vector<int> inOrder (in ,in + 8);

    solution solu;
    TreeNode *root = solu.reConstructBinaryTree(preOrder, inOrder);
    cout << "preOrder";
    TreeNode::PreOrder(root);
    cout << endl;

    cout << "InOrder";
    TreeNode::InOrder(root);
    cout << endl;
    //cout << "Hello World!" << endl;
    return 0;
}


























 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值