iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java二叉树查询原理实例代码分析
  • 670
分享到

Java二叉树查询原理实例代码分析

2023-07-04 15:07:36 670人浏览 泡泡鱼
摘要

这篇文章主要介绍“Java二叉树查询原理实例代码分析”,在日常操作中,相信很多人在Java二叉树查询原理实例代码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java二叉树查询原理实例代码分析”的疑惑有所

这篇文章主要介绍“Java二叉树查询原理实例代码分析”,在日常操作中,相信很多人在Java二叉树查询原理实例代码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java二叉树查询原理实例代码分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

二叉查询树

Java二叉树查询原理实例代码分析

概述

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分

特点

树同时具有数组查询的效率、链表增删、改的性能

右子树的结点比左子树的节点大

查找法

搜索的数字如果比节点大则往右搜索,搜索的数字如果比节点小则往左搜索

结点实现原理

插入实现原理

Java二叉树查询原理实例代码分析

int[] arrs = {5,2,1,4,3,9,7,6,8};

如果树是空树,插入节点就直接放入到根结点

如果树不是空树,则插入的数字于根结点的数字进行比较

如果插入的值小于于结点的数字,则往左子树插入

  • 如果左子结点没有元素就插入到左子结点中

  • 如果左子结点有元素,就可以设计一个引用(游标)指向左子节点,并且再次和待插入的执行左子结点进行比较,直到找到插入的位置

如果插入的值大于结点的数字,则往右子树插入

  • 判断右子结点是否存在值,如果不存在则直接插入

  • 判断右子结点是否存在值,如果存在则通过一个引用指向右子结点继续和待插入的值进行比较,直到找到插入的位置

总结

  • 小往左,大往右

  • 左子数永远小于右子树

遍历实现原理

Java二叉树查询原理实例代码分析

中序遍历:左—根—右

通过中序遍历就可以将二叉树查找树的进行顺序输出

总结:

始终贯彻左—根—右的原则、由内层向外层拆分

int[] arrs = {1,2,3,4,5,6,7,8,9};

删除实现原理

提供一个待删除的结点的值,根据值从二叉查找树找到需要删除的结点

找到待删除结点的父类结点,并且要根据待删除结点在父类结点的左右子树的位置,设置为null进行删除

需要考虑结点的三种情况

情况1:待删除的结点没有子结点

直接让父类结点的对应目标结点引用设置为null即可

情况2:待删除的结点有一个子节点

将待删除的父类结点对应子节点的引用指向待删除结点的子节点

情况3:待删除的结点有两个子节点 从左子树中找到最大的结点进行删除,并且将最大的结点的值放入到待删除结点从右子树中找到最小的结点进行删除,并且将最小的结点的值放入(替换)到待删除结点

(上述两种删除方法:需要将待删除结点指向新创建(替换后的)的结点,并且将新的结点(替换后的)的左右结点指向待删除的左右子树的结点)

删除的结点是根节点的情况

情况1:根节点没有子节点,直接将根结点指向null

情况2:根结点有一个子节点,则根结点直接指向子节点

情况3:根结点有两个子节点

可以从左子树中找到最大值删除结点,然后将最大值覆盖(替换)根节点

可以从右子树中找到最小值删除结点,然后将最小值覆盖(替换)根节点

结点插入与遍历案例

BinarySearchTree类

package AlGorithm;public class BinarySearchTree {    node root;  //定义根节点    //结点插入方法    public void insert(int value) {        if (root == null) {        //1.如果树是空树,插入节点就直接放入到根结点            root = new Node(value);        } else {     //如果树不是空树,则插入的数字于根结点的数字进行比较            //2.如果插入的值小于于结点的数字,则往左子树插入            Node node = root;     //声明一个游标结点,开始指向根节点            while (true) {       //并且再次和待插入的执行左子结点进行比较,直到找到插入的位置                if (value < node.value) {      //如果插入的值小于于结点的数字,则往左子树插入                    //2.1如果左子结点没有元素就插入到左子结点中                    if (node.left == null) {                        node.left = new Node(value);                        break;      //如果找到插入的位置,则跳出while循环                    } else {         //如果左子结点有元素,就可以设计一个引用(游标)指向左子节点,并且再次和待插入的执行左子结点进行比较,直到找到插入的位置                        //游标指向左子节点                        node = node.left;                    }                } else {      //如果插入的值大于结点的数字,则往右子树插入                    //判断右子结点是否存在值,如果不存在则直接插入                    if (node.right == null) {                        node.right = new Node(value);                        break;                    } else {     //判断右子结点是否存在值,如果存在则通过一个引用指向右子结点继续和待插入的值进行比较,直到找到插入的位置                        //游标指向右子节点                        node = node.right;                    }                }            }        }    }    //定义左右结点常量    public static final int LEFT = 0; //左子节点    public static final int RIGHT = 1; //右子节点    //结点查找方法    public void deleteNode(int value) {        //定义游标从根节点开始查询        Node node = root;        //定义目标结点        Node target = null;        //定义目标结点的父类结点        Node parent = null;        //目标结点的类型为,左子节点或者右子节点        int nodeType = 0; //0代表左子节点 1代表右子节点        while (node != null) { //游标不为空,如果为空则没有子节点,无法删除            if (node.value == value) { //如果目标结点的值和需要删除结点的值相同                //找到结点                target = node;                break;            } else if (value < node.value) {    //如果值不同,则判断目标结点值是否小于node结点                //保存父类结点                parent = node;                //游标指向左子节点                node = node.left;                nodeType = LEFT;            } else { //如果值不同,且目标结点值大于node结点                //保存父类结点                parent = node;                //游标指向右子节点                node = node.right;                nodeType = RIGHT;            }        }        //如果没找到需要删除的目标结点        if (target==null){            System.out.println("没有找到要删除的结点");            return;        }        //删除结点的三种情况        if (target.left == null && target.right == null) {   //情况1:待删除的结点没有子结点            if (parent==null){      //删除的结点没有子结点                //将root设置为null即可                root=null;                return;            }            //判断目标的结点是左子节点还是右子节点            if (nodeType == LEFT) {                //将父类的左子节点设置为null                parent.left = null;            } else {                //将父类的右子节点设置为null                parent.right = null;            }        } else if (target.left != null && target.right != null) {   //情况2:待删除的结点有2个子节点            //两个子节点,从target右子树查找最小的值            Node min=target.right;            //遍历左子树            while (min.left!=null){                min = min.left;            }            //将最小的结点进行删除            deleteNode(min.value);            //将待删除的结点替换成最小的结点的值            target.value= min.value;        }else { //情况3:待删除的结点有1个子节点            //删除结点是根节点            if (parent==null){                if (target.left!=null){ //判断是左子节点还是右子节点有值                    root=target.left;   //根节点=目标左子结点                }else {                    root=target.right;  //根节点=目标右子结点                }            }            //只有一个子节点            if (nodeType==LEFT){    //如果是左子节点                if (target.left!=null){                    //将父类的左子节点,指向待删除结点的左子节点                    parent.left=target.left;                }else { //如果是右子节点                    //将父类的左子节点,指向待删除结点的右子节点                    parent.left=target.right;                }            }else {                if (target.right!=null){                    //将父类的右子节点,指向待删除结点的左子节点                    parent.right=target.left;                }else { //如果是右子节点                    //将父类的右子节点,指向待删除结点的右子节点                    parent.right=target.right;                }            }        }    }    //实现中序遍历    public void midTraversal(Node node) {        if (node == null) {  //进行判断结点不能为空,如果为空则退出            return;        } else {     //如果结点不为null,则执行下列遍历语句            //首先,遍历左节点            midTraversal(node.left);            //打印根节点            System.out.print(node.value + ",");            //最后遍历右子结点            midTraversal(node.right);        }    }    //创建一个结点类    public static class Node {        int value;  //存储值        Node left;  //左子树        Node right; //右子树        // 带参构造方法,传入value赋值        public Node(int value) {            this.value = value;        }    }}

TestBST测试

package Algorithm;public class TestBST {    public static void main(String[] args) {        int[] arrs = {5, 2, 1, 4, 3, 9, 7, 6, 8};        //创建二叉查询树        BinarySearchTree tree = new BinarySearchTree();        //将数组中的元素构造成二叉查询树        for (int i = 0; i < arrs.length; i++) {            tree.insert(arrs[i]);        }        //删除结点        tree.deleteNode(20);        //中序遍历根结点        tree.midTraversal(tree.root);    }}

到此,关于“Java二叉树查询原理实例代码分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Java二叉树查询原理实例代码分析

本文链接: https://www.lsjlt.com/news/346225.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL怎么更新字段长度
    要更新MySQL表中的字段长度,可以使用ALTER TABLE语句。以下是更新字段长度的示例: ALTER TABLE table_...
    99+
    2024-05-14
    mysql
  • sql如何修改表字段长度
    要修改表字段的长度,可以使用ALTER TABLE语句,然后使用MODIFY COLUMN来修改字段的长度。以下是一个示例: ALT...
    99+
    2024-05-14
    sql
  • mysql数据量太大如何解决
    有几种方法可以解决MySQL数据量过大的问题: 数据库分区:将数据库表按照某种规则进行分区,分成多个小表,可以提高查询速度和管理...
    99+
    2024-05-14
    mysql
  • MySQL单表数据量过大如何解决
    在MySQL中,当单表的数据量过大时,可以采取以下几种方法来解决问题: 使用索引:在表的字段上创建适当的索引,可以提高查询效率,...
    99+
    2024-05-14
    mysql
  • mysql导出数据量过大如何解决
    当导出的数据量过大时,可以尝试以下方法来解决问题: 使用数据库工具:使用数据库管理工具如Navicat或MySQL Workbe...
    99+
    2024-05-14
    mysql
  • mysql中log_bin的作用是什么
    在MySQL中,log_bin是二进制日志文件的名称,用于记录所有对数据库进行更改的操作,如插入、更新、删除等。这些二进制日志文件可...
    99+
    2024-05-14
    mysql
  • mysql中log_bin的特点有哪些
    log_bin是MySQL的二进制日志文件,用于记录所有对数据库的修改操作,包括插入、更新、删除等。 log_bin文件是M...
    99+
    2024-05-14
    mysql
  • mysql rpm包安装的方法是什么
    要在Linux系统上安装MySQL RPM包,可以按照以下步骤操作: 下载MySQL的RPM包:你可以从MySQL官方网站下载适...
    99+
    2024-05-14
    mysql
  • mysql rpm包安装后怎么使用
    安装MySQL RPM包后,您可以通过以下步骤来使用MySQL: 启动MySQL服务:使用以下命令来启动MySQL服务: sud...
    99+
    2024-05-14
    mysql
  • lxml中怎么处理XML命名空间默认值
    在lxml中处理XML命名空间的默认值可以通过使用xpath()方法和register_namespace()方法来实现。...
    99+
    2024-05-14
    lxml
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作