目录

(1)自定义输出

(2)插入操作add()

(3)判断该BST中是否存在值为val的元素——contains(int val)

(4)查找并返回BST中的最小/最大值——findMin/findMax

(5)删除最小/最大值并返回删除的该值——removeMin/removeMax

(6)删除值为val的元素——removeVal(int val)

(7)修改元素值


(1)自定义输出

  • 按照先序遍历的顺序输出;
  • 唯一不同的是,这里为便于更好的根据输出结果还原二叉树,我们引入用 “--” 连接的分隔符以示节点所在层次,下一层的高度比上一层的“--”长;

如下图,左侧结果即为右图BST的输出形式

 代码实现

//    按先序遍历顺序输出各节点的值public String toString(){StringBuilder s = new StringBuilder();generateString(root,0,s);return s.toString();}private void generateString(TreeNode root, int height, StringBuilder s) {if(root == null){s.append(height(height)).append("Null\n");return;}
//        root不为空,先拼接该根节点s.append(height(height)).append(root.val).append("\n");
//        递归左子树generateString(root.left,height + 1,s);
//        递归右子树generateString(root.right,height + 1,s);}/*** 输出高度为height的分割线长度* @param height* @return*/private String height(int height){StringBuilder s = new StringBuilder();for (int i = 0; i < height; i++) {s.append("--");}return s.toString();}

(2)插入操作add()

使插入后仍保持为二分搜索树

  • 可以发现,待插入的新节点最后一定是插入在了叶子节点位置;
  • 借助递归,通过判断根节点与待插入值的大小,递归插入左子树或右子树,直至走到某个子树最后
    //    向BST中插入值为val的元素元素public void add(int val) {root = add(root, val);}/*** 递归,在以node为根节点的BST中插入值为val的元素** @param node* @param val* @return 新的根节点*/public TreeNode add(TreeNode node, int val) {
//        如果为空树,则插入值即为根节点if (node == null) {TreeNode newNode = new TreeNode(val);return newNode;}
//        如果值小,向左子树中插入if (val < node.val) {node.left = add(node.left, val);}
//        如果值大,向右子树中插入if (val > node.val) {node.right = add(node.right, val);}return node;}

(3)判断该BST中是否存在值为val的元素——contains(int val)

如果一节点的值 == val,说明能找到,返回true;

否则:

  • 如果节点值 > val ,去该节点的左子树中找;
  • 如果节点值 < val,去该节点的右子树中找;

一直走到某节点为空,仍然找不到,说明无该节点,返回false;

    public boolean contains(int val) {return containsRecursion(root,val);}//    还是要递归实现public boolean containsRecursion(TreeNode root, int val) {if (root == null) {return false;}if (root.val == val) {return true;} else if (root.val > val) {return containsRecursion(root.left, val);} else {return containsRecursion(root.right,val);}}

(4)查找并返回BST中的最小/最大值——findMin/findMax

以找最小值为例:

最小值一定是左子树的最左节点;

所以,一直向左走,直到找到某节点不再有左节点

    /*** 查找BST中的最小值* @return*/public int findMin(){
//        记得先判空if(size == 0){throw new NoSuchElementException("BST is empty! cannot find");}TreeNode min = minRecursion(root);return min.val;}//    递归实现,最小值就是左子树的最左节点,这里返回值为TreeNode是方便后续删除最小值时也可直接调用该方法private TreeNode minRecursion(TreeNode node){if(node.left == null){return node;}return minRecursion(node.left);}/*** 查找最大值* @return*/public int findMax(){if(size == 0){throw new NoSuchElementException("BST is empty!!! cannot find");}TreeNode max = maxRecursion(root);return max.val;}//    递归实现,最大值就是右子树的最右节点private TreeNode maxRecursion(TreeNode node) {if(node.right == null){return node;}return maxRecursion(node.right);}

(5)删除最小/最大值并返回删除的该值——removeMin/removeMax

以删除最小值为例:

  1. 先找到最小值节点
  2. 首先该节点一定无左子树,现在只需分析该节点有无右子树:
  • 如果该节点有右子树,只需将该节点删除后让该节点的根节点直接连接该右子树即可
  • 如果该节点无右子树,则右子树为null,我们发现上一种情况的做法仍然适用,因为连接空子树也正好是结果

3.综上,删除待删除结点再将右子树连接即可

如下面这个示例:

代码实现:

    /*** 删除最小值并返回该删除的值为多少** @return*/public int removeMin() {if(size == 0){throw new NoSuchElementException("BST is empty!!! cannot remove the min");}TreeNode min = minRecursion(root);root = removeMinRecursion(root);return min.val;}private TreeNode removeMinRecursion(TreeNode node) {//            说明node就是待删除节点if (node.left == null) {//        先存下右节点TreeNode right = node.right;
//            再删除待删除节点node.right = node = null;size--;
//            最后返回右子树,返回右子树就相当于根右子树直接相连return right;}
//        否则不是待删除节点,则递归左子树node.left = removeMinRecursion(node.left);return node;}/*** 删除最大值并返回该删除的值是多少* @return*/public int removeMax(){if(size == 0){throw new NoSuchElementException("BST is empty!!! cannot remove the max");}TreeNode max = maxRecursion(root);root = removeMaxRecursion(root);return max.val;}private TreeNode removeMaxRecursion(TreeNode node) {if(node.right == null){TreeNode left = node.left;node.right = node = null;size--;return left;}node.right = removeMaxRecursion(node.right);return node;}

(6)删除值为val的元素——removeVal(int val)

  1. 先找到值为val的元素
  2. 分析该元素的左右子节点情况判断如何删除连接
  • 若该元素只有左节点无右节点,则直接拼接左节点即可;
  • 若该元素只有右节点无左节点,则直接拼接右节点即可;
  • 若该元素左右节点都有,则需要找该元素的前驱或后继顶替该节点位置

【前驱:比它小的最近的元素,在BST中,即为该元素左子树中最大的那个】

【后继:比它大的下一个元素,在BST中,即为该元素右子树中最小的那个】

以找前驱为例:

【注意!!!】

在拼接9时,注意(1)、(2)的先后顺序,一定要先拼接(1)再拼接(2),因为(1)左子树会先删除左子树的最大,故应该先处理,如若先拼接(2),则在进行操作(1)删除元素时,会把拼接的右也包含在内,会出错

代码实现:

    /*** 删除值为val的值* @param val*/public void removeVal(int val){if(size == 0){throw new NoSuchElementException("BST is empty!!! cannot remove the val");}root = removeHelper(root,val);}private TreeNode removeHelper(TreeNode node,int val){if(node == null){throw new NoSuchElementException("BST is empty!!! cannot remove the val");}
//        如果node就是待删除元素if(node.val == val){
//            如果只有左子树没有右子树if(node.right == null){TreeNode left = node.left;node.left = node = null;size --;return left;}if(node.left == null){TreeNode right = node.right;node.right = node = null;size--;return right;}
//                此种情况左右子树都不为空
//                找前驱TreeNode pre = maxRecursion(node.left);
//                先连接左边的线,左=删除自身后的子树pre.left = removeMaxRecursion(node.left);
//                再连接右,右直接拼接右即可pre.right = node.right;
//                删除val节点node.right = node.left = node = null;return pre;}else if(node.val < val){node.right = removeHelper(node.right,val);return node;}else{node.left = removeHelper(node.left,val);return node;}}

(7)修改元素值

——BST中只能先删除该元素,再插入新元素实现,即调用上述删除和插入方法

    public void changeVal(int val){removeVal(val);add(val);}

BST内部方法的实现相关推荐

  1. python运行mcmc为何老出错_python中mcmc方法的实现

    MCMC方法在贝叶斯统计中运用很多,MIT发布的EMCEE是实现的比较好的.介绍页面在下面.源代码中examples里的代码可以帮助理解各种功能,特别是line.py 列出了最小二乘法,最大似然法和M ...

  2. jQuery 中 data 方法的实现原理

    jQuery 中 data 方法的实现原理 前言:jQuery 作为前端使用最多最广泛的 JS 库,其源码每个 JSer 都应该研究一下.早就打算看却一直被各种事拖着,上次某公司面试时被问到 jQue ...

  3. python回调类_python 回调函数和回调方法的实现分析

    回调与事件驱动 回调函数有比较重要的意义:它在是事件驱动的体现 我们试想一个场景,如果我们触发了某个事件,比如点击事件 那么只要给这个点击事件绑定一个或多个处理事件,也就是回调函数 我们就可以在点击事 ...

  4. scala 函数方法、函数方法的实现原理

    文章目录 1. 函数&方法 2. 函数&方法的实现原理 1. 函数&方法   scala中方法是类的一部分,而函数是一个对象,可以赋值给一个变量.scala 中的方法跟 Jav ...

  5. sort排序方法的实现原理

    sort 排序方法的实现原理   我们比较常用的是直接调用 JS的 sort方法,围绕原生 JS方法,并结合 V8排序的代码一起来分析,以便碰到类似的 JS排序问题时能够轻松应对.   在开始前请思考 ...

  6. DataList中的按钮触发事件的方法的实现

    DataList中的按钮触发事件的方法的实现 1.要在CommandName中设定名字如:       <asp:Button id="Button1" runat=&quo ...

  7. Java黑皮书课后题第10章:**10.23(实现String类)在Java库中提供了String类,给出你自己对下面方法的实现(将新类命名为MyString2)

    **10.23(实现String类)在Java库中提供了String类,给出你自己对下面方法的实现(将新类命名为MyString2) 题目 简短的吐槽 代码:这里将类名改用Test23_MyStrin ...

  8. JavaScript中子类调用父类方法的实现

    一.前言 最近在项目中,前端框架使用JavaScript面向对象编程,遇到了诸多问题,其中最典型的问题就是子类调用父类(super class)同名方法,也就是如C#中子类中调用父类函数base.** ...

  9. 一文介绍备机重建各种方法的实现机制

    摘要:本文将介绍备机重建各种方法的实现机制,并结合应用场景分析,以及对新增参数的使用建议,以期获得最佳应用效果. 本文分享自华为云社区<先码再看,一文介绍备机重建各种方法的实现机制>,原文 ...

最新文章

  1. Docker Swarm集群搭建
  2. 汇编语言 将a段和b段中的数据依次相加,结果存放在c段中
  3. 计算机上机模拟试题答案,2016计算机二级上机模拟试题及答案
  4. java程序中my.ini_帮忙写个JAVA 读写ini配置文件小程序!!!!!
  5. 域对抗网络Domain adversarial neural network及其应用相关论文
  6. java spite截取_Java內功心法,行為型設計模式
  7. 计算机 画图软件 快捷键大全,教你完整版电脑CAD快捷键大全
  8. 第四十二章 SQL函数 DATEADD
  9. 大数据时代的背景下 校园安防管理软件平台发展变化
  10. python获取阿里巴巴国际站商家信息
  11. 智工教育:一消《技术实务》知识点整理
  12. 常用的UML建模详解
  13. 【Excel】如何使用RegexString正则表达式
  14. 梯度与边缘检测常用算子:Roberts、Prewitt、Sobel、LOG,Canny、Lapacian算子
  15. esp8266烧录Html文件
  16. 附近的人打招呼V1.0
  17. 算法:单圈绝对值编码器处理成多圈的
  18. 六度空间-用图进行BFS遍历
  19. matlab deployment project做什么用的,Project是什么软件?BIM项目管理的必备软件之Project,它的功能和作用你看看就知道了...
  20. Stevey's Google Platforms Rant

热门文章

  1. 360Email:会员邮件营销取胜要点总结
  2. 实现类知乎android客户端关注和取消关注的按钮点击效果
  3. 2008年北京奥运会赛程表—— 08-14
  4. CHB-MIT波士顿儿童医院癫痫EEG脑电数据处理-2D-CNN(四)
  5. 树莓派爱好者基地64位2.0系统更新说明
  6. 【散文】 一个人的旅行
  7. linux uniq按照一列去重,Linux uniq去重方法
  8. 项目实例:KNN预测电影网站用户性别(Hadoop学习笔记三)
  9. 三维组态可视化解决方案
  10. Office 365 2021密钥版 m1芯片支持