力扣:三种遍历方式构造二叉树

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

根据不同遍历方式返回如下二叉树:

    3
   / \
  9  20
    /  \
   15   7

表示:
index:用来寻找并表示左右子树分开的节点。

pre:前序数组
preStart:始指针 preEnd:尾指针

in:中序数组
inStart:始指针 inEnd:尾指针

post:后序数组
postStart:始指针 postEnd:尾指针
从前序与后序遍历序列构造二叉树:
根节点指针为:preStart
由于前序数组的特性(根 左 右)得知,根节点的左子节点为pre[preStart+1],而后序数组的特性(左 右 根),根节点的左子节点在左子树的最后,可得index。
左子树:
后序:[postStart,index]-----(index-postStart) 左子树的数量
前序:[preStart+1,preStart+1+(index-postStart)]
右子树:
后序:[index+1,postEnd-1]-----(postEnd-1-(index+1))右子树的数量
前序:[preEnd-(postEnd-1-(index+1)),preEnd]

代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* constructFromPrePost(vector<int>& pre, vector<int>& post) {
        return helper(pre,post,0,pre.size()-1,0,post.size()-1);
    }
    TreeNode* helper(vector<int>& pre,vector<int>& post,int preStart,int preEnd,int postStart,int postEnd)
    {
        if(postStart>postEnd || preStart>preEnd) return nullptr;
        TreeNode* root = new TreeNode(pre[preStart]);
        if(preStart == preEnd) return root;
        int index = postStart;
        while(pre[preStart+1] != post[index])
        {
            index++;
        }
        root->left = helper(pre,post,preStart+1,preStart+1+(index-postStart),postStart,index);
        root->right = helper(pre,post,preEnd-(postEnd-1-(index+1)),preEnd,index+1,postEnd-1);
        return root;
    }
};

从前序与中序遍历序列构造二叉树:
根节点指针为:preStart
通过根节点指针得知根节点的值,在中序数组中分开左右子树。
左子树:
中序:[inoStart,index-1]
前序:[preStart+1,preStart+1+index-1-inoStart]
右子树:
中序:[index+1,inoEnd]
前序:[preEnd-(inoEnd-(index+1)),preEnd]

代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(vector<int>& pre, vector<int>& ino) {
     return helper(pre,ino,0,pre.size()-1,0,ino.size()-1);   
    }
    TreeNode* helper(vector<int>& pre,vector<int>& ino,int preStart,int preEnd,int inoStart,int inoEnd)
    {
        if(preStart>preEnd || inoStart>inoEnd) return nullptr;
        TreeNode* root = new TreeNode(pre[preStart]);
        if(pre[preStart] == pre[preEnd]) return root;

        int index = inoStart;
        while(pre[preStart] != ino[index])
        {
            index++;
        }
        root->left = helper(pre,ino,preStart+1,preStart+1+index-1-inoStart,inoStart,index-1);
        root->right = helper(pre,ino,preEnd-(inoEnd-(index+1)),preEnd,index+1,inoEnd);
        return root;
    }
};

从中序与后序遍历序列构造二叉树:
根节点的值为:postEnd
通过根节点指针得知根节点的值,在中序数组中分开左右子树。
左子树:
中序:[inoStart,index-1]
后序:[postStart,postStart+(index-1-inoStart)]
右子树:
中序:[index+1,inoEnd]
后序:[postEnd-1-(inoEnd-(index+1)),postEnd-1]

代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(vector<int>& ino, vector<int>& post) {
        return helper(ino,post,0,ino.size()-1,0,post.size()-1);
    }
    TreeNode* helper(vector<int>& ino,vector<int>& post,int inoStart,int inoEnd,int postStart,int postEnd)
    {
        if(inoStart>inoEnd||postStart>postEnd) return nullptr;
        TreeNode* root = new TreeNode(post[postEnd]);
        if(postStart == postEnd) return root;
        int index = inoStart;
        while(post[postEnd] != ino[index])
        {
            index++;
        }
        root->left = helper(ino,post,inoStart,index-1,postStart,postStart+(index-1-inoStart));
        root->right = helper(ino,post,index+1,inoEnd,postEnd-1-(inoEnd-(index+1)),postEnd-1);
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值