树:重建二叉树

先序:根左右

中序:左根右

因此给出的先序,第一个元素就是根,要想确定左先序、左中序、右先序、右中序,需要进中序序列查询根的位置。

则所查询到的位置的左侧是左中序,右侧是右中序。由于知道了左中序和右中序,就能跟着确定左子树和右子树的

节点个数,则可以确定出左先序、右先序。知道左先序、左中序,就可根据这两个序列去求解左子树,知道右先序、

右中序,可根据这两个序列去求解右子树。可以看出这是个递归的过程。递归出口结束的条件是先序序列为空,此时

是空树。


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>

using namespace std;

//注释部分都为做测试所用。
/* 二叉树节点定义
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};*/
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        vector<int>lpre,lin,rpre,rin;
        //lpre存放左先序,lin存放左中序,rpre存放右先序,rin存放右中序
        TreeNode *node;
        if(pre.size()==0)  return NULL;             //节点个数为0,代表当前是空树
        int x = pre[0];                             //先序序列的首元素是二叉树的根
        node = (TreeNode*)malloc(sizeof(TreeNode)); //为定义的节点分配内存
        node->val = x;                              //初始化根节点
        node->left = NULL;
        node->right = NULL;
        int cnt;
        for(cnt = 0; cnt < vin.size(); cnt++) {
            //在中序中找到根,找到后停止。
            if(x == vin[cnt]) {
                break;
            }
        }
        //cnt左侧的元素为左中序
        for(int i = 0; i < cnt; i++) {
            lin.push_back(vin[i]);
        }
        //cnt右侧的元素为右中序
        for(int i = cnt+1; i < vin.size(); i++) {
            rin.push_back(vin[i]);
        }
        //1到cnt。共cnt个元素是左先序
        for(int i = 1; i <= cnt; i++) {
            lpre.push_back(pre[i]);
        }
        //剩余的元素是由先序
        for(int i = cnt+1; i < pre.size(); i++) {
            rpre.push_back(pre[i]);
        }
        //递归构建左右子树
        node->left = reConstructBinaryTree(lpre,lin);
        node->right = reConstructBinaryTree(rpre,rin);
        //返回根
        return node;
    }
};
/* 输出先序遍历结果
void PreOrder(TreeNode *root) {
    if(root != NULL) {
        printf("%d ",root->val);
        PreOrder(root->left);
        PreOrder(root->right);
    }
}
输出中序遍历结果
void InOrder(TreeNode *root) {
    if(root != NULL) {
        InOrder(root->left);
        printf("%d ",root->val);
        InOrder(root->right);
    }
}
int main() {
    int n,x;
    while(~scanf("%d",&n)) {
        vector<int>pre,in;
        for(int i = 0; i < n; i++) {
            scanf("%d",&x);
            pre.push_back(x);
        }
        for(int i = 0; i < n; i++) {
            scanf("%d",&x);
            in.push_back(x);
        }
        TreeNode *root;
        Solution s;
        root = s.reConstructBinaryTree(pre,in);
        printf("****************************\n");
        PreOrder(root);
        printf("\n");
        InOrder(root);
        printf("\n");
    }
    return 0;
}

8
1 2 4 7 3 5 6 8
4 7 2 1 5 3 8 6
*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值