广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >二叉搜索树
  • 210
分享到

二叉搜索树

java算法数据结构 2023-09-01 17:09:07 210人浏览 安东尼
摘要

💕人生没有太晚的开始,所有的时刻都是七点。 —— 温妮 · 普赖弗曼💕 🐼作者:不能再留遗憾了 🎆专栏:Java学习 Ὡ

💕人生没有太晚的开始,所有的时刻都是七点。 —— 温妮 · 普赖弗曼💕
🐼作者:不能再留遗憾了
🎆专栏:Java学习
🚗本文章主要内容:明解什么是二叉搜索树以及二叉搜索树的递归和非递归查找、插入和删除。
在这里插入图片描述

文章目录

什么是二叉搜索树

二叉搜索树(Binary Search Tree,也叫做BST)是一种常见的二叉树,但是它具有普通二叉树不具备的性质:
1.对于每个节点,他的左子树中所有节点的键值小于它的键值,而右子树中的所有节点的键值大于它的键值。
2.没有键值相同的节点。(因为二叉搜索树的主要作用是搜索查找数据,而不是存储数据)

在这里插入图片描述

二叉搜索树的查找

因为二叉搜索树的节点的键值大于左子树所有节点的键值,小于于右子树所有结点的所有的键值。所以我们在查找的时候至少可以少找一个子树,这就大大降低了时间的消耗。我们在查找的时候只需要比较要查找的数据的节点键值的大小,如果大于节点的键值,那么就在该节点的右子树上找,小于就在左子树上找,重复该操作,直到找到需要的值,返回该节点,没找到就返回null。

在这里插入图片描述

非递归查找

public class BinarySearchTree {//我们创建一个树内部类,包含键值和左右子树    static class Treenode {        public int val;        public TreeNode left;        public TreeNode right;        public TreeNode(int val) {            this.val = val;        }    }    public TreeNode root = null;    //查找    public TreeNode find(int val) {        TreeNode cur = root;        while(cur != null) {            if(cur.val == val) {                return cur;            }else if(cur.val > val) {                cur = cur.left;            }else {                cur = cur.right;            }        }        return null;    }}

递归查找

public class BinarySearchTree {    static class TreeNode {        public int val;        public TreeNode left;        public TreeNode right;        public TreeNode(int val) {            this.val = val;        }    }    public TreeNode root = null;    //查找    public TreeNode find(int val) {        TreeNode cur = root;        return findChild(cur,val);    }    //递归查找    private TreeNode findChild(TreeNode cur,int val) {        if(cur == null) {            return null;        }        if(cur.val == val) {            return cur;        }else if(val > cur.val) {            cur = findChild(cur.right,val);        }else {            cur = findChild(cur.left,val);        }        return cur;    }

构建二叉搜索树(插入数据)

当一开始二叉树为空树时,我们第一个插入的数据,或者我们可以选取一个数据,要求这个数据的左子树的键值都小于它,右子树的键值都大于它,将这个数据作为二叉搜索树的根节点。
当二叉搜索树中存在节点的时候,我们再插入数据的时候就需要判断待插入的数据与节点的键值的关系了,如果待插入的数据小于节点的键值,那么说明待插入的数据一定在该节点的左子树上,如果待插入的数据大于节点的键值,那么待插入的数据就一定插在该节点的右子树上。并且我们不难发现:我们新插入的节点总是插在树的树叶上。所以当我们的遍历节点cur到达null时就判断待插入的数据与cur的父亲节点parent的关系,然后将新节点插入到parent的左子树或者右子树。

在这里插入图片描述

非递归插入

public void insert(int val) {//判断再插入数据之前该树是否为空树        if(root == null) {            root = new TreeNode(val);            return;        }        TreeNode cur = root;        //我们需要记住cur的父亲节点,方便将cur与parent连接        TreeNode parent = null;        while(cur != null) {            if(cur.val > val) {                parent = cur;                cur = cur.left;            }else if(cur.val < val) {                parent = cur;                cur = cur.right;            }else {            //这种是相等的情况,因为二叉搜索树中不存在相同的键值,所以我们直接返回                return;            }        }        //这里我们判断是插入到parent的左子树上还是右子树上        if(val > parent.val) {            parent.right = new TreeNode(val);        }else {            parent.left = new TreeNode(val);        }    }

递归插入

public void insert(int val) {//当插入之前树为空树时,将待插入数据作为树的根节点        if(root == null) {            root = new TreeNode(val);            return;        }        TreeNode parent = null;        TreeNode cur = root;        insertChild(parent,cur,val);    }    public void insertChild(TreeNode parent,TreeNode cur,int val) {        if(cur == null) {            if (parent.val < val) {                parent.right = new TreeNode(val);                return;            } else if (parent.val > val) {                parent.left = new TreeNode(val);                return;            } else {                return;            }        }        if(cur.val > val) {            insertChild(cur,cur.left,val);        }else if(cur.val < val){            insertChild(cur,cur.right,val);        }else {        return;        }    }

二叉搜索树的删除

俗话说:“请神容易,送神难”。我们往二叉搜索树中插入数据很简单,但是要是想删除数据,那可就不简单了,不像数组,数组删除数据只需要将要删除的数据的后面的一个一个向前覆盖就行了。但是二叉搜索树可没那么容易,因为你删除数据之后既要保证它是一个二叉树,还要保证它是二叉搜索树,不能破坏二叉搜索树的结构。

如果想要删除数据,我们需要分情况讨论:1.要删除的节点的左子树为空时。2.要删除的节点的右子树为空时。3.要删除的节点的左右子树都不为空时。前两种情况相对于左右子树都不为空这种情况较简单,我们先来看看前两种情况该怎么做。

当左子树或者右子树为空时

在这里插入图片描述

当右子树为空时,操作跟左子树为空类似,只是需要判断待删除的节点是在parent的左子树上还是右子树上。并且还有一种特殊情况,当待删除的节点为root根节点时,我们只需要将root变化一下就行了。

public void revome(int val) {        TreeNode cur = root;        TreeNode parent = null;        //找到待删除的节点        while(cur != null) {            if(cur.val > val) {                parent = cur;                cur = cur.left;            }else if(cur.val < val) {                parent  = cur;                cur = cur.right;            }else {            //删除节点                removeChild(parent,cur);            }        }    }private void removeChild(TreeNode parent,TreeNode cur) {        if(cur.left == null) {        //当cur = null时            if(cur == root) {                root = root.right;            }else if(parent.left == cur) {                parent.left = cur.right;            }else {                parent.right = cur.right;            }        }else if(cur.right == null) {            if(cur == root) {                root = root.right;            }else if(parent.left == cur) {                parent.left = cur.left;            }else {                parent.right = cur.left;            }        }    }

当左子树和右子树都不为空时

当待删除的节点的左右子树都不能空时,我们可以用该节点的左子树的最右边的节点(左子树的键值最大的节点)或者右子树最左边的节点(右子树键值最小的节点)取代这个待删除的节点,然后再删除这个节点。为什么要选择这两个节点呢?因为这两个节点的键值与待删除的节点的键值最相近,选取这两个数据替代待删除的数据不会破坏二叉搜索树的结构。

在这里插入图片描述

//在右子树中找最小节点TreeNode targetP = cur;TreeNode target = cur.right;while(target.left != null) {targetP = target;    target = target.left;}cur.val = target.val;if(targetP.left == target) {   targetP.left = target.right;   }else {   targetP.right = target.right;   }}

删除操作整体代码

public void revome(int val) {        TreeNode cur = root;        TreeNode parent = null;        while(cur != null) {            if(cur.val > val) {                parent = cur;                cur = cur.left;            }else if(cur.val < val) {                parent  = cur;                cur = cur.right;            }else {                removeChild(parent,cur);            }        }    }    private void removeChild(TreeNode parent,TreeNode cur) {        if(cur.left == null) {            if(cur == root) {                root = root.right;            }else if(parent.left == cur) {                parent.left = cur.right;            }else {                parent.right = cur.right;            }        }else if(cur.right == null) {            if(cur == root) {                root = root.right;            }else if(parent.left == cur) {                parent.left = cur.left;            }else {                parent.right = cur.left;            }        }else {            TreeNode targetP = cur;            TreeNode target = cur.right;            while(target.left != null) {                targetP = target;                target = target.left;            }            cur.val = target.val;            if(targetP.left == target) {                targetP.left = target.right;            }else {                targetP.right = target.right;            }        }    }

总结

总之,二叉排序树以链接的方式存储,保持了链接存储结构在执行插入或删除操作时不用移动元素的优点,只要找到合适的插入和删除位置后,仅需修改链接指针即可。插入删除的时间性能比较好。而对于二叉排序树的查找,走的就是从根结点到要查找的结点的路径,其比较次数等于给定值的结点在二叉排序树中的层数。极端情况,最少为1次,即根结点就是要找的结点,最多也不会超过树的深度。也就是说,二叉排序树的查找性能取决于二叉排序树的形状。可问题就在于,二叉排序树的形状是不确定的。
例如{62,88,58,47,35,73,51,99,37,93}这样的数组,我们可以构建如下图1所示的二叉排序树。但如果数组元素的次序是从小到大有序,如{35,37,47,51,58,62,73,88,93,99},则二叉排序树就成了极端的右斜树,注意它依然是一棵二叉排序树,如下图2。此时,同样是查找结点99,下图1只需要两次比较,而下图2就需要10次比较才可以得到结果,二者差异很大。

在这里插入图片描述
在这里插入图片描述
这个问题可以用AVL树以及跟高级的红黑树来解决,我们后面再介绍。

来源地址:https://blog.csdn.net/m0_73888323/article/details/130709134

--结束END--

本文标题: 二叉搜索树

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

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

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

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

下载Word文档
猜你喜欢
  • 二叉搜索树
    💕人生没有太晚的开始,所有的时刻都是七点。 —— 温妮 · 普赖弗曼💕 🐼作者:不能再留遗憾了 🎆专栏:Java学习 Ὡ...
    99+
    2023-09-01
    java 算法 数据结构
  • 二叉搜索树(C++)
    二叉搜索树 概念二叉搜索树的应用二叉搜索树的实现K模型基本结构和函数声明接口实现①find——查找关键码②Insert——插入关键码③Erase——删除关键码(==重点==)时间复杂度 源码(整体)非递归递归 ...
    99+
    2023-08-30
    c++
  • 何为二叉搜索树
    本篇内容主要讲解“何为二叉搜索树”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“何为二叉搜索树”吧!什么是树树是一种数据结构,它是由n(n>=1)个有限结点...
    99+
    2022-10-19
  • Python实现二叉搜索树
    二叉搜索树 我们已经知道了在一个集合中获取键值对的两种不同的方法。回忆一下这些集合是如何实现ADT(抽象数据类型)MAP的。我们讨论两种ADT MAP的实现方式,基于列表的二分查找和哈希表。在这一节中,我...
    99+
    2022-06-04
    Python
  • 利用java实现二叉搜索树
    目录二叉搜索树的定义实现一颗二叉搜索树二叉搜索树的定义类二叉搜索树的查找二叉搜索树的插入二叉搜索树的删除二叉搜索树的定义 它是一颗二叉树 任一节点的左子树上的所有节...
    99+
    2022-11-12
  • C++二叉搜索树实例分析
    本篇内容介绍了“C++二叉搜索树实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!独一无二的二叉搜索树Given an integer&...
    99+
    2023-06-19
  • Java中关于二叉树的概念以及搜索二叉树详解
    目录一、二叉树的概念为什么要使用二叉树?树是什么?树的相关术语!根节点路径父节点子节点叶节点子树访问层(深度)关键字满二叉树完全二叉树二叉树的五大性质二、搜索二叉树插入删除hello...
    99+
    2022-11-12
  • C++二叉搜索树BSTree如何使用
    这篇文章主要介绍“C++二叉搜索树BSTree如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++二叉搜索树BSTree如何使用”文章能帮助大家解决问题。一、概念二叉搜索树又称二叉排序树,它...
    99+
    2023-07-05
  • java数据结构之搜索二叉树
    本文实例为大家分享了java数据结构之搜索二叉树的具体代码,供大家参考,具体内容如下 搜索二叉树的定义是:在一个二叉树上,左节点一定比父节点小,右节点一定比父节点大,其他定义跟二叉树...
    99+
    2022-11-12
  • C++二叉搜索树BSTree使用详解
    目录一、概念二、基础操作1.查找find2.插入Insert3.中序遍历InOrder4.删除erase三、递归写法1.递归查找2.递归插入3.递归删除四、应用五、题目练习一、概念 ...
    99+
    2023-03-09
    C++二叉搜索树BSTree C++二叉搜索树 C++ BSTree
  • C++怎么把二叉搜索树转换累加树
    今天小编给大家分享一下C++怎么把二叉搜索树转换累加树的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。把二叉搜索树转换为累加树...
    99+
    2023-07-04
  • C++LeetCode0538二叉搜索树转换累加树示例
    目录LeetCode 538把二叉搜索树转换为累加树方法一:DFS反向中序遍历AC代码C++LeetCode 538把二叉搜索树转换为累加树 力扣题目链接:lee...
    99+
    2022-12-16
    C++ 二叉搜索树转换累加树 C++ LeetCode
  • java基础二叉搜索树图文详解
    目录概念直接实践准备工作:定义一个树节点的类,和二叉搜索树的类。搜索二叉树的查找功能搜索二叉树的插入操作搜索二叉树 删除节点的操作 - 难点性能分析总程序 - 模拟实现二叉搜索树和 ...
    99+
    2022-11-13
  • 如何利用JavaScript实现二叉搜索树
    计算机科学中最常用和讨论最多的数据结构之一是二叉搜索树。这通常是引入的第一个具有非线性插入算法的数据结构。二叉搜索树类似于双链表,每个节点包含一些数据,以及两个指向其他节点的指针;它...
    99+
    2022-11-12
  • C++实现LeetCode(98.验证二叉搜索树)
    [LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树 Given a binary tree, determine if it is ...
    99+
    2022-11-12
  • C++实现LeetCode(99.复原二叉搜索树)
    [LeetCode] 99. Recover Binary Search Tree 复原二叉搜索树 Two elements of a binary search tree (BST...
    99+
    2022-11-12
  • C++深入细致探究二叉搜索树
    目录1、二叉搜索树的概念2、二叉搜索树的操作二叉搜索树的查找二叉搜索树的插入二叉搜索树的删除3、二叉搜索树的实现4、二叉搜索树的性能分析1、二叉搜索树的概念  二叉搜索树又...
    99+
    2022-11-13
  • JavaScript二叉搜索树构建操作详解
    目录前言什么是二叉搜索树构建一颗二叉搜索树二叉搜索树的操作向二叉搜索树中插入数据查找二叉搜索树中的数据删除二叉搜索树的某个节点前驱后继节点删除一个节点的三种情况实现代码完整代码总结前...
    99+
    2022-11-13
  • 怎么利用JavaScript实现二叉搜索树
    这篇文章给大家分享的是有关怎么利用JavaScript实现二叉搜索树的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。计算机科学中最常用和讨论最多的数据结构之一是二叉搜索树。这通常是引入的第一个具有非线性插入算法的数...
    99+
    2023-06-14
  • C++实现验证二叉搜索树代码
    本篇内容主要讲解“C++实现验证二叉搜索树代码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++实现验证二叉搜索树代码”吧!验证二叉搜索树Given a binary tree, determ...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作