剑指offer笔记重建二叉树

Posted AllenSquirrel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer笔记重建二叉树相关的知识,希望对你有一定的参考价值。

目录

 

题目:根据遍历结构构造二叉树

若题目告知前序和中序遍历结构 ,如何构建一棵二叉树?

若题目告知中序和后序遍历结构 ,如何构建一棵二叉树?


  • 题目:根据遍历结构构造二叉树

前序遍历:根 -> 左 ->  右

中序遍历:左 -> 根 ->  右

后序遍历:左 -> 右 ->  根

  • 若题目告知前序和中序遍历结构 ,如何构建一棵二叉树?

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* _build(vector<int>& preorder, vector<int>& inorder,int& preidx,int start,int end)
    {
        if(start>end)//不包含任何元素
            return nullptr;
        TreeNode* cur=new TreeNode(preorder[preidx]);
        //左右子树区间
        int curidx=start;
        for(;curidx<=end;curidx++)
        {
            if(inorder[curidx]==preorder[preidx])
                break;//找到分界点curidx
        }
        if(start<curidx)
        {
            cur->left=_build(preorder,inorder,++preidx,start,curidx-1);
        }
        else
            cur->left=nullptr;
        if(curidx<end)
        {
            cur->right=_build(preorder,inorder,++preidx,curidx+1,end);
        }
        else
            cur->right=nullptr;

        return cur;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int previdx=0;
        return _build(preorder,inorder,previdx,0,inorder.size()-1);
    }
};

上述代码,通过_build函数实现二叉树构建,其中采用递归思想分别构建左子树和右子树,根据前序节点作为划分依据依次在中序序列中划分, 根据划分结果递归构建左子树和右子树,直至左右子树为空停止递归,结束构建

  • 若题目告知中序和后序遍历结构 ,如何构建一棵二叉树?

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]

 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* _build(vector<int>& inorder, vector<int>& postorder,int& postidx,int start,int end)
    {
        if(start>end)
            return nullptr;
        TreeNode* cur=new TreeNode(postorder[postidx]);
        int curidx=start;
        for(;curidx<=end;curidx++)
        {
            if(inorder[curidx]==postorder[postidx])
                break;
        }
        if(curidx<end)
        {
            cur->right=_build(inorder,postorder,--postidx,curidx+1,end);
        }
        else
        {
            cur->right=nullptr;
        }
        if(curidx>start)
         {
            cur->left=_build(inorder,postorder,--postidx,start,curidx-1);
        }
        else
        {
            cur->left=nullptr;
        }
        return cur;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        int postidx=postorder.size()-1;
        return _build(inorder,postorder,postidx,0,inorder.size()-1);
    }
};

 上述代码,通过_build函数实现二叉树构建,其中采用递归思想分别构建右子树和左子树,根据后序节点作为划分依据依次在中序序列中划分, 根据划分结果递归构建右子树和左子树,直至左右子树为空停止递归,结束构建

注:

无论是从前序和中序构建,还是从后序和中序构建,二者思想类似,均采用递归思想完成子树构建,需要注意的是,前序遍历顺序是根左右,所以构建过程中先递归构建左子树,再递归构建右子树,而后序遍历顺序是左右根,从后往前找,先找到右子树根,所以构建过程中先递归构建右子树,再递归构建左子树

以上是关于剑指offer笔记重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章

java刷题-剑指offer 07 重建二叉树

剑指offer重建二叉树python

剑指offer重建二叉树

《剑指offer》— JavaScript重建二叉树

剑指 Offer 07. 重建二叉树(java解题)

剑指Offer07 重建二叉树