栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 构造二叉树如此简单

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 构造二叉树如此简单

文章目录
    • 一、由中序和后序遍历构造二叉树
      • 1. 题目
      • 2. 题目分析
      • 3. 代码
    • 二、由前序和中序遍历构造二叉树
    • 三、总结

一、由中序和后序遍历构造二叉树 1. 题目

根据一棵树的中序遍历与后序遍历构造二叉树。

注意:你可以假设树中没有重复的元素。

例如,给出

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

2. 题目分析

可以借助二叉树后序遍历最后一个值为根节点的值,以此为分界线可以将中序遍历数组分为两部分

以此为基础,层层切割

切割过程中会产生区间,为了方便处理,需要统一设置,左闭右闭的区间 []

使用后序的最后一个值划分中序,再依据中序划分出来的两个区间的长度对后序进行划分

3. 代码
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (inorder.length == 0 || postorder.length == 0) {
            return null;
        }
        //采用左闭右闭的规则
        return createBinaryTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);

    }

    public TreeNode createBinaryTree(int[] in, int inBegin, int inEnd, int[] post, int postBegin, int postEnd) {
        if (inBegin > inEnd || postBegin > postEnd) {
            return null;
        }
        TreeNode root = new TreeNode(post[postEnd]);
        for (int i = inBegin; i <= inEnd; i++) {
            //下标 i 表示中序数组中根节点的下标
            if (in[i] == root.val) {
                //数组区间均是左闭右闭 [begin,end]
                root.left = createBinaryTree(in, inBegin, i - 1, post, postBegin, postBegin + i - 1 - inBegin);
                root.right = createBinaryTree(in, i + 1, inEnd, post, postBegin + i - inBegin, postEnd - 1);
                break;
            }
        }
        return root;
    }
}
二、由前序和中序遍历构造二叉树

该题思路和上面这道题相同

只是,这里由前序的第一个元素我根节点,划分中序集合

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder.length == 0 || inorder.length == 0) {
            return null;
        }
        return createTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
    }

    public TreeNode createTree(int[] pre, int preBegin, int preEnd, int[] in, int inBegin, int inEnd) {
        if (preBegin > preEnd || inBegin > inEnd) {
            return null;
        }
        TreeNode root = new TreeNode(pre[preBegin]);
        for (int i = inBegin; i <= inEnd; i++) {
            if (in[i] == root.val) {
                root.left = createTree(pre, preBegin + 1, preBegin + i - inBegin, in, inBegin, i - 1);
                root.right = createTree(pre, preBegin + 1 + i - inBegin, preEnd, in, i + 1, inEnd);
                break;
            }
        }
        return root;
    }
}
三、总结

创建二叉树,思路类似,都是依据前序首位元素或者后序的末尾元素,来划分中序集合

划分过程,注意区间的长度大小,定义开闭区间需要统一,这里统一定义左闭右闭

比如:

root.left = createTree(pre, preBegin + 1, preBegin + i - inBegin, in, inBegin, i - 1);

已知中序集合的区间为[inBegin,i-1],所以可以确定前序的左半区间长度也为:i-1-inBegin

已知,前序的首位preBegin为根元素,所以左半区间其实元素下标为 preBegin+1,又知长度为 i-1-inBegin,所以前序集合左半区间为[preBegin+1,preBegin+1+i-1-inBegin]

技巧:此时正好i-1-inBegin = preBegin+1+i-1-inBegin - (preBegin+1)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/591229.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号