【数据结构】用Java实现一棵二叉树

这篇具有很好参考价值的文章主要介绍了【数据结构】用Java实现一棵二叉树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

1. 创建MyBinaryTree类

2. 从前序与中序遍历序列构造二叉树

3. 从中序与后序遍历序列构造二叉树

4. 用层序遍历验证二叉树是否构建成功

5. 整体代码(构建二叉树、二叉树的基本功能和测试代码)

6. 测试结果


前言

前面两篇文章已经给出了如何构建二叉树以及如何实现基本功能,感兴趣的友友可以点下面的链接看一看,在这里给出构建二叉树的简单说明以及构建二叉树和实现基本功能实现的代码。

二叉树的构建

二叉树的基本操作

    // 前序遍历
    void preOrder(TreeNode root);  
    // 中序遍历
    void inOrder(TreeNode root);
    // 后序遍历
    void postOrder(TreeNode root);
    
    // 获取树中节点的个数:遍历思路
    public static int nodeSize;
    void size(TreeNode root);
 
    // 获取节点的个数:子问题的思路
    int size2(TreeNode root);
    //获取叶子节点的个数:遍历思路
    public static int leafSize = 0;
    void getLeafNodeCount1(TreeNode root);
 
    // 获取叶子节点的个数:子问题
    int getLeafNodeCount2(TreeNode root);
 
    // 获取第K层节点的个数
    int getKLevelNodeCount(TreeNode root, int k);
 
    // 获取二叉树的高度,时间复杂度:O(N)
    int getHeight(TreeNode root);
 
    // 检测值为value的元素是否存在
    TreeNode find(TreeNode root, char val);
 
    //层序遍历
    void levelOrder(TreeNode root);
 
    // 判断一棵树是不是完全二叉树
    boolean isCompleteTree(TreeNode root);

1. 创建MyBinaryTree类

val存储二叉树节点的值,left为二叉树的左子树,right为二叉树右子树地址。

下面的所有方法都是在MyBinaryTree类中实现的。

public class MyBinaryTree {
    static class TreeNode {
        public int val;
        TreeNode left;//左孩子的引用
        TreeNode right;//右孩子的引用

        public TreeNode(int val) {
            this.val = val;
        }
    }

}

2. 从前序与中序遍历序列构造二叉树

从前序遍历中获取根节点,中序遍历中根节点前面的是左子树的部分,中序遍历中根节点后面的是右子树部分。使用index下标来遍历前序数组。

1. 从前序遍历结果中获取到树的根节点

2. 在中序遍历结果中确定根节点的位置,按照该位置将中序遍历结果分为两部分

        左半部分是根节点的左子树,递归创建根节点的左子树

        右半部分是根节点的右子树,递归创建根节点的右子树

public TreeNode buildTree1(int[] preorder, int[] inorder) {
        return buildTreeHelper1(preorder,inorder,0,inorder.length - 1);
    }
    int index = 0;
    private TreeNode buildTreeHelper1(int[] preorder, int[] inorder, int left, int right) {
        if(index == inorder.length ){
            return null;
        }
        if (left > right){
            return null;
        }
        int pos = find(inorder,preorder);
        TreeNode root = new TreeNode(preorder[index]);
        index ++;
        root.left = buildTreeHelper1(preorder,inorder,left,pos - 1);
        root.right = buildTreeHelper1(preorder,inorder,pos + 1,right);
        return root;
    }
    private int find(int[] inorder,int[] preorder) {
        for (int i = 0; i < inorder.length; i++) {
            if (inorder[i] == preorder[index]){
                return i;
            }
        }
        return -1;
    }

3. 从中序与后序遍历序列构造二叉树

先看看同一颗树的前序遍历结果preorder = [3,9,20,15,7]和后序遍历的结果postorder = [9,15,7,20,3],对比一下这两。

发现将后序遍历的结果反转->[3,20,7,15,9],前序遍历是根左右,后序遍历反转后的是根右左,所以我们只需要将后序遍历的结果反转一下,然后向上一题那样构建二叉树,只不过是先构建右子树再构建左子树。

//    从中序与后序遍历序列构造二叉树, 返回这棵树的根节点
    public TreeNode buildTree2(int[] postorder, int[] inorder) {
        reverse(postorder);
        return buildTreeHelper2(postorder,inorder,0,inorder.length - 1);
    }
    private void reverse(int[] postorder){
        for (int i = 0; i < postorder.length/2; i++) {
            int temp = postorder[i];
            postorder[i] = postorder[postorder.length - i - 1];
            postorder[postorder.length - i - 1] = temp;
        }
    }
    private TreeNode buildTreeHelper2(int[] postorder, int[] inorder, int left, int right) {
        if(index == inorder.length ){
            return null;
        }
        if (left > right){
            return null;
        }
        int pos = find(inorder,postorder);
        TreeNode root = new TreeNode(postorder[index]);
        index ++;
        root.right = buildTreeHelper2(postorder,inorder,pos + 1,right);
        root.left = buildTreeHelper2(postorder,inorder,left,pos - 1);
        return root;
    }

4. 用层序遍历验证二叉树是否构建成功

1. 如果是空树直接返回

2. 层序遍历需要用到队列,定义一个队列,里面放置节点的地址,将根节点如队列

3. 队列非空时,循环进行一下操作:

        a. 队列中当前元素都是在同一层的,依次取出遍历,保存到同一个curList中

        取到一个节点时候,

                >> 保存该节点

                >> 如果该节点左子树存在,将该左子树入队列

                >> 如果该节点右子树存在,将该节点右子树入队列

                 >> 将当前已遍历节点从队列中拿出来

         b. 本层节点遍历结束后,保存到返回的curList中,此时下一层节点已经全部入队列

public void levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        if (root == null){
            System.out.println(list);
            return;
        }
        Deque<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            int size = queue.size();
            List<Integer> curList = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode temp = queue.pop();
                curList.add(temp.val);
                if (temp.left != null){
                    queue.offer(temp.left);
                }
                if (temp.right != null){
                    queue.offer(temp.right);
                }
            }
            list.add(curList);
        }
        System.out.println(list);
    }

5. 整体代码(构建二叉树、二叉树的基本功能和测试代码)

构建的二叉树:

java 构造二叉树,数据结构,数据结构,java,二叉树

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class MyBinaryTree {
    static class TreeNode {
        public int val;
        TreeNode left;//左孩子的引用
        TreeNode right;//右孩子的引用

        public TreeNode(int val) {
            this.val = val;
        }
    }

//    从前序与中序遍历序列构造二叉树, 返回这棵树的根节点
    public TreeNode buildTree1(int[] preorder, int[] inorder) {
        return buildTreeHelper1(preorder,inorder,0,inorder.length - 1);
    }
    int index = 0;
    private TreeNode buildTreeHelper1(int[] preorder, int[] inorder, int left, int right) {
        if(index == inorder.length ){
            return null;
        }
        if (left > right){
            return null;
        }
        int pos = find(inorder,preorder);
        TreeNode root = new TreeNode(preorder[index]);
        index ++;
        root.left = buildTreeHelper1(preorder,inorder,left,pos - 1);
        root.right = buildTreeHelper1(preorder,inorder,pos + 1,right);
        return root;
    }
    private int find(int[] inorder,int[] preorder) {
        for (int i = 0; i < inorder.length; i++) {
            if (inorder[i] == preorder[index]){
                return i;
            }
        }
        return -1;
    }

//    从中序与后序遍历序列构造二叉树, 返回这棵树的根节点
    public TreeNode buildTree2(int[] postorder, int[] inorder) {
        reverse(postorder);
        return buildTreeHelper2(postorder,inorder,0,inorder.length - 1);
    }
    private void reverse(int[] postorder){
        for (int i = 0; i < postorder.length/2; i++) {
            int temp = postorder[i];
            postorder[i] = postorder[postorder.length - i - 1];
            postorder[postorder.length - i - 1] = temp;
        }
    }
    private TreeNode buildTreeHelper2(int[] postorder, int[] inorder, int left, int right) {
        if(index == inorder.length ){
            return null;
        }
        if (left > right){
            return null;
        }
        int pos = find(inorder,postorder);
        TreeNode root = new TreeNode(postorder[index]);
        index ++;
        root.right = buildTreeHelper2(postorder,inorder,pos + 1,right);
        root.left = buildTreeHelper2(postorder,inorder,left,pos - 1);
        return root;
    }

//    层序遍历
//    用数组输出层序遍历结果
    public void levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        if (root == null){
            System.out.println(list);
            return;
        }
        Deque<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            int size = queue.size();
            List<Integer> curList = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode temp = queue.pop();
                curList.add(temp.val);
                if (temp.left != null){
                    queue.offer(temp.left);
                }
                if (temp.right != null){
                    queue.offer(temp.right);
                }
            }
            list.add(curList);
        }
        System.out.println(list);
    }
//    直接输出结果
//    void levelOrder(TreeNode root) {
//        if (root == null){
//            System.out.println("这是颗空树!!!");
//            return;
//        }
//        Deque<TreeNode> queue = new LinkedList<>();
//        queue.offer(root);
//        while (!queue.isEmpty()){
//            TreeNode cur = queue.pop();
//            System.out.print(cur.val + " ");
//            if (cur.left != null){
//                queue.offer(cur.left);
//            }
//            if (cur.right != null){
//                queue.offer(cur.right);
//            }
//        }
//    }

    // 前序遍历
    public void preOrder(TreeNode root) {
        if(root == null){
            return;
        }
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    }

    // 中序遍历
    void inOrder(TreeNode root) {
        if(root == null){
            return;
        }
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    }

    // 后序遍历
    void postOrder(TreeNode root) {
        if(root == null){
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val + " ");
    }

    public static int nodeSize;

    /**
     * 获取树中节点的个数:遍历思路
     */
    void size(TreeNode root) {
        if (root == null){
            return;
        }
        nodeSize ++;
        size(root.left);
        size(root.right);
    }

    /**
     * 获取节点的个数:子问题的思路
     */
    int size2(TreeNode root) {
        if (root == null) return 0;
        return size2(root.left) + size2(root.right) + 1;
    }


    /*
     获取叶子节点的个数:遍历思路
     */
    public static int leafSize = 0;

    void getLeafNodeCount1(TreeNode root) {
        if(root == null){
            return;
        }
        if (root.left == null && root.right == null){
            leafSize ++;
        }
        getLeafNodeCount1(root.left);
        getLeafNodeCount1(root.right);
    }

    /*
     获取叶子节点的个数:子问题
     */
    int getLeafNodeCount2(TreeNode root) {
        if (root == null) return 0;
        if (root.left == null && root.right == null) {
            return 1;
        }
        return getLeafNodeCount2(root.left) + getLeafNodeCount2(root.right);
    }

    /*
    获取第K层节点的个数
     */
    int getKLevelNodeCount(TreeNode root, int k) {
        if (root == null || k <= 0){
            return 0;
        }
        if (k == 1){
            return 1;
        }
        return getKLevelNodeCount(root.left,k - 1) + getKLevelNodeCount(root.right,k - 1);
    }

    /*
     获取二叉树的高度
     时间复杂度:O(N)
     */
    int getHeight(TreeNode root) {
        if (root == null){
            return 0;
        }
        if(root.left == null && root.right == null){
            return 1;
        }
        return 1 + Math.max(getHeight(root.left),getHeight(root.right));
    }


    // 检测值为value的元素是否存在
    TreeNode find(TreeNode root, char val) {
        if (root == null){
            return null;
        }
        if (root.val == val){
            return root;
        }
        TreeNode node = find(root.left,val);
        if (node != null){
            return node;
        }
        return find(root.right,val);
    }


    // 判断一棵树是不是完全二叉树
    boolean isCompleteTree(TreeNode root) {
        Deque<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        boolean isStep1 = true;
        while (!queue.isEmpty()){
            TreeNode node = queue.poll();
            if(isStep1){
                if(node.left != null && node.right != null){
                    queue.offer(node.left);
                    queue.offer(node.right);
                } else if (node.left != null) {
                    queue.offer(node.left);
                    isStep1 = false;
                } else if (node.right != null){
                    return false;
                }else {
                    isStep1 = false;
                }
            }else {
                if(node.left != null || node.right != null){
                    return false;
                }
            }
        }
        return true;
    }

    public static void main(String[] args) {
        MyBinaryTree tree = new MyBinaryTree();
        //用前序遍历和后序遍历构建二叉树
        int[] pre = {3,9,20,15,7};
        int[] in = {9,3,15,20,7};
        TreeNode root = tree.buildTree1(pre,in);

        System.out.println("前序遍历");
        tree.preOrder(root);
        System.out.println();
        System.out.println("中序遍历");
        tree.inOrder(root);
        System.out.println();
        System.out.println("后序遍历");
        tree.postOrder(root);
        System.out.println();
        System.out.println("层序遍历");
        tree.levelOrder(root);
        System.out.println();
        System.out.println("统计树的节点个数");
        tree.size(root);
        System.out.println(nodeSize);
        System.out.println("统计叶子节点个数");
        tree.getLeafNodeCount1(root);
        System.out.println(leafSize);
        System.out.println("树的高度");
        System.out.println(tree.getHeight(root));

        System.out.println("检测树中值为val的元素是否存在 Q  B");
//        System.out.println(tree.find(root,'x').val);
        if (tree.find(root,'Q') == null){
            System.out.println("没有找到该元素");
        }else {
            System.out.println(tree.find(root,'x').val);
        }
        if (tree.find(root,'B') == null){
            System.out.println("没有找到该元素");
        }else {
            System.out.println(tree.find(root,'B').val);
        }
        System.out.println("获取第K层节点的个数");
        System.out.println(tree.getKLevelNodeCount(root,3));

        System.out.println("判断一棵树是不是完全二叉树");
        System.out.println(tree.isCompleteTree(root));

    }
}

6. 测试结果

java 构造二叉树,数据结构,数据结构,java,二叉树文章来源地址https://www.toymoban.com/news/detail-676584.html

到了这里,关于【数据结构】用Java实现一棵二叉树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【gdb调试】在ubuntu环境使用gdb调试一棵四层二叉树的数据结构详解

    目录 🌞1. 整体思路 🌞2. 准备内容 🌼2.1 配置.c文件 🌼2.2 准备测试程序 🌼2.3 GDB调试基础 🌞3. GDB调试四层二叉树 🌼3.1 测试程序分析 🌼3.2 gdb分析 🌻1. 设置断点 🌻2. 启动程序并执行到断点处 🌻3. 打印变量的值 🌻4. 单步执行 s 进入buildTree函数内部 a. 第一层:根节点赋

    2024年04月17日
    浏览(17)
  • 数据结构(Java实现)-二叉树(下)

    获取二叉树的高度 检测值为value的元素是否存在(前序遍历) 层序遍历 判断一棵树是不是完全二叉树 获取节点的路径 二叉树的最近公共祖先

    2024年02月10日
    浏览(29)
  • 数据结构(Java实现)-二叉树(上)

    树型结构 树是一种非线性的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点,称为根结点,根结点没有前驱结点 除根结点外,其余结点被分成M(M 0)个互不

    2024年02月11日
    浏览(29)
  • 【Java 数据结构】实现一个二叉搜索树

    目录   1、认识二叉搜索树 2、实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法  2.4 remove 方法(重点) 3、二叉搜索树总结 从字面上来看,它只比二叉树多了搜索两个字,我们回想一下,如果要是在二叉树中查找一个元素的话,需要遍历这棵树,效率很慢,而二叉搜

    2024年02月02日
    浏览(30)
  • Java 数据结构篇-实现二叉搜索树的核心方法

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍   文章目录         1.0 二叉搜索树的概述         2.0 二叉搜索树的成员变量及其构造方法         3.0 实现二叉树的核心接口         3.1 实现二叉搜索树 - 获取值 get(int key)         3.2 实现二叉搜索树

    2024年02月04日
    浏览(37)
  • Java 数据结构篇-二叉树的深度优先遍历(实现:递归方式、非递归方式)

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍    文章目录         1.0 二叉树的说明         1.1 二叉树的实现         2.0 二叉树的优先遍历说明         3.0 用递归方式实现二叉树遍历         3.1 用递归方式实现遍历 - 前序遍历         3.2 用递归

    2024年02月05日
    浏览(38)
  • 数据结构中的一棵树

    一、树是什么? 有根有枝叶便是树!根只有一个,枝叶可以有,也可以没有,可以有一个,也可以有很多。 就像这样: 嗯,应该是这样: 二、一些概念 1、高度 树有多高,嗯,我一米八三! 树的高度怎么算? 高度是啥,就是从下往上到最顶端,从叶节点到根节点。 从每个

    2024年01月21日
    浏览(24)
  • 手撕数据结构与算法——树(三指针描述一棵树)

    📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段, 因为最近参加新星计划算法赛道(白佬),所以加快了脚步,果然急迫感会增加动力 ——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的 📖作者主页:king南星 📖

    2024年01月17日
    浏览(38)
  • 【Java 数据结构】二叉树

    树是一种 非线性 的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。 有一个特殊的结点,称为根结点,根结点没有前驱结点 除根结点外,其余结点被分成M(M 0)个互不相交的

    2024年02月20日
    浏览(32)
  • 【java数据结构-二叉树(上)】

    🔥个人主页: 努力学编程’ 🔥内容管理: java数据结构 hello,今天带大家学习 数据结构 中非常重要的一个知识点 二叉树 ,二叉树主体的实现使用的是递归的知识,通过二叉树我们可以更好的理解递归的应用。今天就带大家学习一下二叉树的一些知识。 概念 : 树是一种非

    2024年04月08日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包