一棵二叉查找树(BST)是一颗二叉树,其中每个节点都含有一个Comparable的键且每个节点的键(以及相关的值)都大于其左子树中的任意节点的键而小于右子树的任意结点的键。

数据表示

和链表一样,我们嵌套定义了一个私有类来表示二叉查找树上的一个节点。每个节点都含有一个键、一个值、一条左链接、一条右链接和一个节点计数器

查找节点

思路:

A、如果二叉查找树为空,查找失败(search miss),返回null;

B、如果根节点的键等于要查找的键,返回根节点的值(search hit)。

C、否则,继续在相应的子树中查找。如果要查找的键小于根节点的键,在左子树中查找;如果要查找的键大于根节点的键,在右子树中查找。

D、重复ABC步骤,直至search miss或者search hit。

插入节点

思路:

A、如果二叉查找树是空的,生成一个新节点,并返回该节点,相当于插入新节点后的二叉树根节点。

B、如果根节点键和要插入的键相等,更新根节点的值。

C、如果要插入的键小于根节点的键,在左子树插入,并将根节点的左链接指向插入后的左子树。

D、如果要插入的键小于根节点的键,在右子树插入,并将根节点的右链接指向插入后的右子树。

E、更新根节点的size,并返回根节点,作为插入新节点后的二叉树根节点。

F、重复ABCD,直至插入或者更新成功。

删除节点

删除节点是二叉搜索树中,最复杂的一种操作,但是也不是特别难,我们分类讨论:

  1. 要删除节点有零个孩子,即叶子节点

如图所示,只需要将parent.left设置为null,然后Java垃圾自动回收机制会自动删除current节点。

2.要删除节点有一个孩子

如图所示,只需要将parent.left设置为curren.right即可。

3.要删除节点有两个孩子

这种情况比较复杂,首先我们引入后继节点的概念,如果将一棵二叉树按照中序周游的方式输出,则任一节点的下一个节点就是该节点的后继节点。例如:上图中24的后继节点为26,64的后继节点为70.找到后继节点以后,问题就变得简单了,因为但删除节点有右子树,所以它的后继节点就是右子树中的最小节点。

分为两种情况:

  • 后继节点为待删除节点的右子,只需要将curren用successor替换即可,注意处理好current.left和successor.right.

注意:这种情况下,successor一定没有左孩子,一但它有左孩子,哪它必然不是current的后继节点。

  • 后继节点为待删除结点的右孩子的左子树,这种情况稍微复杂点,请看动态图片演示。

删除节点分4步

(1)将只想即将被删除的的节点链接保存为t

(2)将x指向它的后继节点min(t.right)

(3)将x的右链接指向deleteMin(x.right)

(4)将x的左链接设为t.left

实现

package find;public class BST, Value> {    private Node root;    public Value get(Key key) {        return get(root, key);    }    //插入操作    public void put(Key key, Value val) {        root = put(root, key, val);    }    //查询    private Value get(Node x, Key key) {        if (x == null) {            return null;        }        int cmp = key.compareTo(x.key);        if (cmp < 0) {            return get(x.left, key);        } else if (cmp > 0) {            return get(x.right, key);        } else {            return x.val;        }    }    private Node put(Node x, Key key, Value val) {        if (x == null) {            return new Node(key, val, 1);        }        int cmp = key.compareTo(x.key);        if (cmp < 0) {            x.left = put(x.left, key, val);        } else if (cmp > 0) {            x.right = put(x.right, key, val);        } else {            x.val = val;        }        x.N = size(x.left) + size(x.right) + 1;        return x;    }    public int size() {        return size(root);    }    private int size(Node x) {        if (x == null) {            return 0;        } else {            return x.N;        }    }    public Key min() {        return min(root).key;    }    private Node min(Node x) {        if (x.left == null) {            return x;        }        return min(x.left);    }    public Key floor(Key key) {        Node x = floor(root, key);        if (x == null) {            return null;        }        return x.key;    }    private Node floor(Node x, Key key) {        if (x == null) return null;        int cmp = key.compareTo(x.key);        if (cmp == 0) {            return x;        } else if (cmp < 0) {            return floor(x.left, key);        }        Node t = floor(x.right, key);        if (t != null) {            return t;        } else {            return x;        }    }    public void deleteMin() {        root = deleteMin(root);    }    private Node deleteMin(Node x) {        if (x == null) {            return x.right;        }        x.left = deleteMin(x.left);        x.N = size(x.left) + size(x.right) + 1;        return x;    }    public void delete(Key key) {        root = delete(root, key);    }    private Node delete(Node x, Key key) {        if (x == null) {            return null;        }        int cmp = key.compareTo(key);        if (cmp < 0) {            x.left = delete(x.left, key);        } else if (cmp > 0) {            x.right = delete(x.right, key);        } else {            if (x.right == null) {                return x.left;            } else if (x.left == null) {                return x.right;            }            Node t = x;            x = min(t.right);            x.right = deleteMin(t.right);            x.left = t.left;        }        x.N = size(x.left) + size(x.right) + 1;        return x;    }    private class Node {        private Key key;        private Value val;        private Node left, right;        private int N;        public Node(Key key, Value val, int N) {            this.key = key;            this.val = val;            this.N = N;        }    }}

xdocument查找节点值_二叉查找树(java)相关推荐

  1. java中怎么表示数组中的某个值_简易Java(12):如何高效检查一个数组中是否包含某个值?...

    如何检查一个数组(未排序)中是否包含某个特定的值?在Java中,这是一个非常有用并又很常用的操作.同时,在StackOverflow中,有时一个得票非常高的问题.在得票比较高的几个回答中,时间复杂度差 ...

  2. java如何获取数组中的属性值_【java】查找对象数组中某属性的最大值, 然后返回该项的其他属性值...

    有一个数组,里面装的都是对象. var array=[ { "id": 52354541, "name": "比率", "valu ...

  3. java compare 返回值_关于Java你不知道的那些事之Java8新特性[Lambda表达式和函数式接口]...

    前言 为什么要用Lambda表达式? Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码,将代码像数据一样传递,这样可以写出更简洁.更灵活的代码,作为一个更紧凑的代码风 ...

  4. Java怎么查找字符串大写_在Java中,如何检查字符串是否包含子字符串(忽略大小写)?...

    本问题已经有最佳答案,请猛点这里访问. 我有两个String s,str1和str2. 如何检查str1是否包含在str1中,忽略大小写? indexOf和contains都是逐个字符的,所以如果你需 ...

  5. java jcombobox 获取值_从java中的JComboBox获取字符串值

    我正在做一个testJComboBox程序.一旦我选择了jCombobox的输出,我就会得到我需要的字符串值.但是,它不起作用. 这是我的代码: import java.awt.*; import j ...

  6. Java反射设置list的属性值_利用java反射比较两个实体有哪些属性值不一样

    分享一个利用反射实现比较两个实体属性值的方法: package net.zwq1105.test; import java.beans.Introspector; import java.beans. ...

  7. 几百万的数据查找重复值_如何快速查找出Excel中的重复数据,多角度分析

    如何多角度查找出重复数据,是数据分析中必不可少的一项.办公中经常遇到重复数据,想要标识出来,再进一步分析,避免数据出错.像人事部门,经常遇到同名不同人这种情况,如果工资发错了,很容易出现大问题,如何来 ...

  8. boolean类型默认值_【Java基础】还在问String属于什么数据类型

    1.前言 首先提出一个问题在 Java 中 String 属于那种数据类型? 我的一个朋友是这么说的,「what?是不是有很多疑惑,int.double.String 不都是经常一起使用的么,应该都是 ...

  9. java 怎么获取键的值_在 Java 中如何获取 Map 的所有键和值

    在 Java 中可以通过 map.entrySet() 方法获取 Map 的所有键和值. Map map = new HashMap<>(); // Get keys and values ...

最新文章

  1. c语言socket句柄函数传递,通过源码解析 Node.js 中进程间通信中的 socket 句柄传递...
  2. 二维数组的查找 java_二维数组中的查找
  3. jquery操作dom
  4. 2021-01-13 Matlab求解微分代数方程 (DAE)
  5. Scrapy框架的学习(7. 了解Scrapy中的debug信息以及Scrapy shell的使用)
  6. 你需要的git命令大全来了
  7. Spring Mvc使用Jackson进行json转对象时,遇到的字符串转日期的异常处理(Can not deserialize value of type Date from String)
  8. CGContextRef使用简要教程
  9. 使用 Dawn 构建 React 项目
  10. UITextField监控文字变化方法
  11. Java计算机毕业设计德云社票务系统源码+系统+数据库+lw文档
  12. MD5破解实验与个人的MD5暴破程序介绍
  13. 时序分解股票数据并部署在微信公众号上
  14. AD 删除原理图图纸外的器件
  15. Cache 的地址映像方式(4种)
  16. ResNet网络详解
  17. MPI编程----计算cosx的积分
  18. 安装vue@4出现报错ERR! code EEXIST npm ERR! path C:\Users\beaty-Ida\AppData\Roaming\npm\node_modules\@vue\c
  19. 计算机打字比赛通知,打字比赛通知
  20. PLC实现S速度曲线的几种方式

热门文章

  1. Thinking in Java 源代码 source code 在IDEA上运行
  2. [机器学习] 推荐系统之协同过滤算法(转)
  3. 028 -bash-4.1$ 出现故障的原理及解决办法?
  4. 根据HTML5 获取当前位置的经纬度【百度地图】【高德地图】
  5. MyBatis 事务源码分析
  6. node --- 后端使用bcrypt对密码进行加密处理
  7. AtomicIntegerArray和AtomicIntegerFieldUpdater
  8. 我与Linux系统的交集
  9. Undefined symbols for architecture i386:_OBJC_CLASS_$_xx, referenced from: 解决方法
  10. 分布式消息队列 Kafka