广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >【Java 数据结构】实现一个二叉搜索树
  • 543
分享到

【Java 数据结构】实现一个二叉搜索树

数据结构算法二叉搜索树 2023-09-02 20:09:32 543人浏览 安东尼
摘要

目录  1、认识二叉搜索树 2、实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法  2.4 remove 方法(重点) 3、二叉搜索树总结 1、认识二叉搜索树 从字面上来看,它只比二叉树多


目录 

1、认识二叉搜索树

2、实现一个二叉搜索树

2.1 成员变量

2.2 insert 方法

2.3 search 方法 

2.4 remove 方法(重点)

3、二叉搜索树总结


1、认识二叉搜索树

从字面上来看,它只比二叉树多了搜索两个字,我们回想一下,如果要是在二叉树中查找一个元素的话,需要遍历这棵树,效率很慢,而二叉搜索树,则会效率高很多,为什么呢?

二叉搜索树,可以是一棵空树,或者是具有以下的性质:

  • 若它的左子树不为空,则左树上所有的节点都小于根节点
  • 若它的右子树不为空,则右树上所有节点的都大于根节点
  • 它的左子树和右子树也分别为二叉搜索树

通俗来讲,左孩子都小于父节点,右孩子都大于父节点,以此类推,这里我们画图来认识下二叉搜索树:

当然二叉搜索树不要求是完全二叉树或满二叉树,甚至会出现单分支的二叉搜索树,所以针对这种特殊的情况进行了优化也就延申而来的 AVL树,这个是后续的话题。

仔细观察上图,可以观察出二叉搜索树的一个新特性:

中序遍历二叉搜索树是有序的,所以二叉搜索树也被称为二叉排序


2、实现一个二叉搜索树

2.1 成员变量

public class BinarySearchTree {    private Treenode root; //存放根节点    private static class TreeNode {        private int val;        private TreeNode left;        private TreeNode right;        private TreeNode(int val) {            this.val = val;        }    }}

 这里跟我们的二叉树成员变量大同小异,主要是去实现插入,查找,删除的逻辑。

2.2 insert 方法

往二叉搜索树插入一个节点的时候,我们要注意两点,首先如果二叉搜索树为空,则直接令 root 为当前插入的节点即可,那如果二叉搜索树不为空,我们则需要利用二叉搜索树的性质,找到该节点要插入的位置即可,具体我们来看下图:

通过动图我们可以看到,当二叉搜索树不为空的时候,新的元素会依次节点比较,如果比根节点大,则去根的右边,比根节点小,则取根的左边,以此类推。(搜索二叉树不存在相同的元素)

但是我们用代码如何实现呢?定义一个 cur 引用,当 cur 等于 null 了,则表示是我要插入的位置,既然找到了要插入的位置,但是还得知道这个位置的父节点是谁,通过父节点的指针域给连接起来,于是代码可以这样写:

public boolean insert(int key) {    // 二叉搜索树没有节点的情况    if (root == null) {        root = new TreeNode(key);        return true;    }    // 二叉搜索树不为空的情况 -> 找到该节点要插入的位置进行插入    // 如果已经存在该节点了, 则不用插入 -> 二叉搜索树中不能出现重复值    TreeNode parent = null; // 记录cur的父节点    TreeNode cur = root;    while (cur != null) {        if (cur.val < key) {            parent = cur;            cur = cur.right;        } else if (cur.val > key) {            parent = cur;            cur = cur.left;        } else {            return false; // 插入重复的节点        }    }    // 走到这, cur为空了, key 需要插入到 parent 的左节点或右节点中    TreeNode newNode = new TreeNode(key);    if (parent.val < key) {        parent.right = newNode;    } else {        parent.left = newNode;    }    return true;}

2.3 search 方法 

搜索方法,也就是给一个 key 你,让你在这颗二叉树找有没有这个元素,有的话返回该节点,没有的话返回 null,这个就很简单了, 跟上面的步骤一样无非就是碰到相同的元素返回 cur 嘛,当 cur 根据 key 遍历完这棵二叉搜索树的时候,也就是 cur 为 null 了,则表示没有该元素,直接返回 null即可。

代码如下:

public TreeNode search(int key) {    TreeNode cur = root;    while (cur != null) {        if (cur.val < key) {            cur = cur.right;        } else if (cur.val > key) {            cur = cur.left;        } else {            return cur;        }    }    return null;}

2.4 remove 方法(重点)

在二叉搜索树中,删除一个节点是一个比较麻烦的事,但是只要把各种删除的情况下列举出来,一一解决它即可,对于二叉搜索树来说,你删除了一个节点,它仍然满足二叉搜索树的性质。

设 cur 为要删除的节点,所以首先我们得判断这个二叉搜索树中,是否存在要删除的节点,这个逻辑上面已经写过了,找到要删除的节点后,我们一共会面临三种情况:

① 如果 cur 没有左子树的情况

  • 如果 cur 是 root 的情况,只需要 root = cur.right
  • 如果 cur 不是 root,cur 是 parent.left 的情况,只需要 parent.left = cur.right
  • 如果 cur 不是 root,cur 是 parent.right 的情况,只需要 parent.right = cur.right

图解: 

 ② 如果 cur 没有右子树的情况

  • 如果 cur 是 root 的情况,只需要 root = cur.left
  • 如果 cur 不是 root,cur 是 parent.left 的情况,只需要 parent.left = cur.left
  • 如果 cur 不是 root,cur 是 parent.right 的情况,只需要 parent.right = cur.left

图解: 

③ 如果 cur 既有左子树,又有右子树的情况

  • 使用替换法进行删除,即在 cur 的右子树中,一直往左寻找最小的元素,将这个最小值赋值给要删除节点的 val 值中,接着把这个最小元素的节点删除即可,删除的逻辑见下图和完整删除代码。

 

代码如下:

public boolean remove(int key) {    TreeNode parent = null;    TreeNode cur = root;    while (cur != null) {        if (cur.val < key) {            parent = cur;            cur = cur.right;        } else if (cur.val > key) {            parent = cur;            cur = cur.left;        } else {            removeNode(parent, cur);            return true;        }    }    return false;}private void removeNode(TreeNode parent, TreeNode cur) {    if (cur.left == null) {        if (cur == root) {            root = cur.right;        } else if (cur == parent.left) {            parent.left = cur.right;        } else {            parent.right = cur.right;        }    } else if (cur.right == null) {        if (cur == root) {            root = cur.left;        } else if (cur == parent.left) {            parent.left = cur.left;        } else {            parent.right = cur.left;        }    } else {        TreeNode target = cur.right;        TreeNode targetParent = cur;        while (target.left != null) {            targetParent = target;            target = target.left;        }        // 走到这, target就是要删除节点的右子树中最小的节点, 接下来进行覆盖        cur.val = target.val;        // 覆盖完成, 现在需要删除 target 节点        // 如果 cur.right 没有左孩子的情况, 此时的target就是cur.right        // 即直接将 cur.right 覆盖到 cur 位置, 也就是满足 target == targetParent.right 条件        // 所以需要进行特殊处理.        if (target == targetParent.right) {            targetParent.right = target.right;        } else {            targetParent.left = target.right;        }    }}

3、二叉搜索树总结

二叉搜索树在最好的情况下为完全二叉树,查找的平均比较次数为:logn

二叉搜索树在最差的情况下退化成但分支,查找的平均比较次数为:n/2

所以二叉搜索树在最差的情况下效率是不高的,为了解决单分支的情况,于是有了 AVL树,当发现二叉搜索树左右子树高度差太大,会自动旋转,以致平衡,避免旋转的次数太多,又引入了红黑树,给节点增加了颜色,细节部分后期讲解,这里有个概念即可,下期将会介绍由红黑树作为底层的集合:TreeSet 和 TreeMap


下期预告: 【Java 数据结构】TreeSet 和 TreeMap

来源地址:https://blog.csdn.net/m0_61784621/article/details/128405350

--结束END--

本文标题: 【Java 数据结构】实现一个二叉搜索树

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

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

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

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

下载Word文档
猜你喜欢
  • 【Java 数据结构】实现一个二叉搜索树
    目录  1、认识二叉搜索树 2、实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法  2.4 remove 方法(重点) 3、二叉搜索树总结 1、认识二叉搜索树 从字面上来看,它只比二叉树多...
    99+
    2023-09-02
    数据结构 算法 二叉搜索树
  • java数据结构之搜索二叉树
    本文实例为大家分享了java数据结构之搜索二叉树的具体代码,供大家参考,具体内容如下 搜索二叉树的定义是:在一个二叉树上,左节点一定比父节点小,右节点一定比父节点大,其他定义跟二叉树...
    99+
    2022-11-12
  • Java数据结构之二叉搜索树详解
    目录前言性质实现节点结构初始化插入节点查找节点删除节点最后前言 今天leetcode的每日一题450是关于删除二叉搜索树节点的,题目要求删除指定值的节点,并且需要保证二叉搜索树性质不...
    99+
    2022-11-13
  • C++数据结构之搜索二叉树的实现
    目录零.前言1.概念2.作用3.迭代实现(1)查找(2)插入(3)删除4.递归实现(1)查找(2)插入(3)删除5.key/value模型的应用(1)对应查找(2)判断出现次数6.总...
    99+
    2022-11-13
  • Java数据结构之二叉搜索树实例分析
    这篇文章主要介绍“Java数据结构之二叉搜索树实例分析”,在日常操作中,相信很多人在Java数据结构之二叉搜索树实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java数据结构之二叉搜索树实例分析”的疑...
    99+
    2023-06-30
  • Java数据结构超详细分析二叉搜索树
    目录1.搜索树的概念2.二叉搜索树的简单实现2.1查找2.2插入2.3删除2.4修改3.二叉搜索树的性能 1.搜索树的概念 二叉搜索树是一种特殊的二叉树,又称二叉查找树,二叉排序树,...
    99+
    2022-11-13
  • C++数据结构之二叉搜索树的实现详解
    目录前言介绍实现节点的实现二叉搜索树的查找二叉搜索树的插入二叉搜索树的删除总结前言 今天我们来学一个新的数据结构:二叉搜索树。 介绍 二叉搜索树也称作二叉排序树,它具有以下性质: 非...
    99+
    2022-11-13
  • Java简单几步实现一个二叉搜索树
    目录1、认识二叉搜索树2、实现一个二叉搜索树2.1 成员变量2.2 insert 方法2.3 search 方法2.4 remove 方法(重点)3、二叉搜索树总结1、认识二叉搜索树...
    99+
    2023-02-08
    Java二叉搜索树 Java二叉树
  • C++详解数据结构中的搜索二叉树
    目录定义查找某个元素构造搜索二叉树往搜索二叉树中插入元素搜索二叉树删除节点定义 搜索二叉树,也称有序二叉树,排序二叉树,是指一棵空树或者具有下列性质的二叉树: 1、若任意节点的左子树...
    99+
    2022-11-13
  • Java数据结构之线索化二叉树的实现
    目录1.线索化二叉树的介绍2.线索化二叉树的基本特点3.线索化二叉树的应用案例4.前序线索化二叉树、遍历5.后序线索化二叉树1.线索化二叉树的介绍 将数列 {1, 3, 6, 8, ...
    99+
    2022-11-13
  • 【Java 数据结构】树和二叉树
    篮球哥温馨提示:编程的同时不要忘记锻炼哦! 一棵倒立过来的树.  目录 1、什么是树? 1.1 简单认识树  1.2 树的概念  1.3 树的表示形式 2、二叉树 2.1 二叉树的概念 2.2 特殊的二叉树...
    99+
    2023-09-17
    算法 数据结构
  • C++数据结构二叉搜索树的实现应用与分析
    目录概念二叉搜索树的实现基本框架二叉搜索树的插入二叉搜索树的查找二叉搜索树的删除(重点)二叉搜索树的应用二叉树性能分析总结⭐️博客代码已上传至gitee:https://gitee....
    99+
    2022-11-13
  • Java数据结构之线索化二叉树怎么实现
    这篇文章主要介绍“Java数据结构之线索化二叉树怎么实现”,在日常操作中,相信很多人在Java数据结构之线索化二叉树怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java数据结构之线索化二叉树怎么实现...
    99+
    2023-06-30
  • 利用java实现二叉搜索树
    目录二叉搜索树的定义实现一颗二叉搜索树二叉搜索树的定义类二叉搜索树的查找二叉搜索树的插入二叉搜索树的删除二叉搜索树的定义 它是一颗二叉树 任一节点的左子树上的所有节...
    99+
    2022-11-12
  • 使用JavaScript怎么实现一个二叉搜索树
    今天就跟大家聊聊有关使用JavaScript怎么实现一个二叉搜索树,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。JavaScript可以做什么1.可以使网页具有交互性,例如响应用户点...
    99+
    2023-06-07
  • Java数据结构之二叉排序树的实现
    目录1 二叉排序树的概述2 二叉排序树的构建2.1 类架构2.2 查找的方法2.3 插入的方法2.4 查找最大值和最小值2.5 删除的方法3 二叉排序树的总结1 二叉排序树的概述 本...
    99+
    2022-11-13
  • Java数据结构之二叉查找树的实现
    目录定义节点结构查找算法插入算法删除算法完整代码定义 二叉查找树(亦称二叉搜索树、二叉排序树)是一棵二叉树,且各结点关键词互异,其中根序列按其关键词递增排列。 等价描述:二叉查找树中...
    99+
    2022-11-13
  • Java数据结构学习之二叉树
    一、背景知识:树(Tree) 在之前的笔记中,我们介绍的链表、栈、队列、数组和字符串都是以线性结构来组织数据的。本篇笔记要介绍的树采用的是树状结构,这是一种非线性的数据组织形式。 树...
    99+
    2022-11-12
  • Java深入了解数据结构之二叉搜索树增插删创详解
    目录①概念②操作-查找③操作-插入④操作-删除1. cur.left == null2. cur.right == null3. cur.left != null &&...
    99+
    2022-11-13
  • C++实现LeetCode(96.独一无二的二叉搜索树)
    [LeetCode] 96. Unique Binary Search Trees 独一无二的二叉搜索树 Given n, how many structurally un...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作