二叉树学习笔记

构造二叉树问题

  1. 构造出根结点。
  2. 递归构造出左子树、右子树。
  3. 返回根结点。

最大二叉树

在这里插入图片描述
1.找出当前序列中的最大值,构造出根结点。
2.然后根据最大值的位置左右划分出两个子序列,递归构造出左右子树。
3.返回根结点。

class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return bulid(nums,0,nums.size()-1);
    }
    TreeNode* bulid(vector<int>& nums,int l,int r){
        if(l > r)
            return NULL;
        int index = -1;
        int maxVal = INT_MIN;
        for(int i = l;i <= r;i++){
            if(nums[i]> maxVal){
                index = i;
                maxVal = nums[i];
            }
        }
        TreeNode *root = new TreeNode(maxVal);
        root->left = bulid(nums,l,index-1);
        root->right = bulid(nums,index + 1,r);
        return root;
    }
};

由前序序列中序序列构造二叉树

前序序列=根+左子树前序序列+右子树前序序列
中序序列=左子树中序序列+根+右子树中序序列

1.由前序序列的第一个元素值构造出根结点。
2.在中序序列中找到根结点值的位置,由此位置划分出左右两个子序列,这两个子序列分别为左子树和右子树的中序序列。
由左子树的中序序列长度可以得到左子树和右子树的的前序序列长度。根据此长度在前序序列中划分出左右子树的前序序列。由左前序和左中序构造出左子树,由右前序和右中序构造出左子树。
3.最后返回根结点。

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
    }
    TreeNode* build(vector<int>& preorder,int preStart,int preEnd,vector<int>& inorder,int inStart,int inEnd){
        if(preStart>preEnd || inStart>inEnd)
            return nullptr;
                       
        int rootVal = preorder[preStart];
        int index = 0;
        for(int i = inStart;i <= inEnd;i++){
            if(inorder[i] == rootVal)
                index = i;
        }
        int leftSize = index - inStart;

        TreeNode *root = new TreeNode(rootVal);
        root->left = build(preorder, preStart + 1,preStart + leftSize ,inorder, inStart,index - 1);
        root->right = build(preorder, preStart + leftSize + 1, preEnd,inorder, index + 1,inEnd);
        return root;
    }
};

由后序序列和中序序列构造二叉树

后序序列=左子树后序序列+右子树后序序列+根
中序序列=左子树中序序列+根+右子树中序序列

1.由后序序列的最后一个元素值构造出根结点。
2.在中序序列中找到根结点值的位置,由此位置划分出左右两个子序列,这两个子序列分别为左子树和右子树的中序序列。
由左子树的中序序列长度可以得到左子树和右子树的的后序序列长度。根据此长度在后序序列中划分出左右子树的后序序列。由左后序和左中序构造出左子树,由右后序和右中序构造出左子树。
3.最后返回根结点。

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return build(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
    }
    TreeNode *build(vector<int>& inorder,int inStart,int inEnd, vector<int>& postorder,int postStart,int postEnd){
        if(inStart>inEnd || postStart>postEnd)
            return nullptr;
        int rootVal = postorder[postEnd];
        int index = 0;
        for(int i = inStart;i <= inEnd;i++){
            if(inorder[i] == rootVal)
                index = i;
        }
        int leftSize = index - inStart;
        TreeNode *root = new TreeNode(rootVal);
        root->left = build(inorder,inStart,index - 1,postorder,postStart,postStart + leftSize -1);
        root->right = build(inorder,index + 1,inEnd,postorder,postStart + leftSize,postEnd - 1);
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值