剑指offer 7:重建二叉树

写在最前

因为各种各样的原因,要开始准备春招,所以开始刷剑指offer(第二版)。

题意

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

这个是个二叉树很基础的题啦,需要用递归来实现。主要讲解在书的62页,主要贴自己的代码和自己的理解。

主要利用的规律如下图:

利用前序中序构建二叉树

代码

//这里我们递归开始之前传入的是整个pre和in数组,然后在之后的递归中再改变pre和in的大小
struct TreeNode *test(int *pre_start, int *pre_end, int *in_start, int *in_end) {
    //创建一个节点并malloc
    struct TreeNode *root = (struct TreeNode *) malloc(sizeof(struct TreeNode));
    //把这个节点赋值为当前的pre的第一个数,因为根据规律,这个数是根节点
    root->val = *pre_start;
    root->left = NULL;
    root->right = NULL;
    //如果首尾相等,说明到了递归最后的终止条件了,只有一个节点了,就返回这个节点
    if (pre_end == pre_start)
        return root;
    //然后我们在中序遍历的数组中要找到和前序遍历根节点相等的节点,然后记下到这个节点的长度,这个长度就是左子树的长度
    //就是根据上图找到左右子树,然后再构建
    int left_len = 0;
    for (int i = 0; i <= (in_end - in_start); i++)
        if (in_start[i] == root->val) {
            left_len = i;
            break;
        }
    //如果左子树的长度大于0,就构建左子树
    if (left_len > 0)
        root->left = test(pre_start + 1, pre_start + left_len, in_start, in_start + left_len - 1);
    //右子树大于0就构建右子树
    if (in_end - in_start >= left_len + 1)
        root->right = test(pre_start + left_len + 1, pre_end, in_start + left_len + 1, in_end);
    //最后返回构建的根节点
    return root;
}


class Solution {
public:
    //题目给的要求传进来的参数是两个vector,所以想要做递归,还需要改成数组形式才可以
    TreeNode *reConstructBinaryTree(vector<int> pre, vector<int> vin) {
        //&pre[0]就是把vector直接变成数组。然后传入到递归函数中
        return test(&pre[0],&pre[0]+pre.size()-1,&vin[0],&vin[0]+vin.size()-1);
    }
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章