【数据结构】什么是二叉查找树(BST)
什么是二叉查找树(BST)
1. 什么是BST
对于二叉树中的每个节点X,它的左子树中所有项的值都小于X中的项,它的右子树中所有项的值大于X中的项。这样的二叉树是二叉查找树。

以上是一颗二叉查找树,其特点是:
(1)若它的左子树不为空,则左子树上的所有节点的值都小于它的根节点的值;
(2)若它的右子树不为空,则右子树上所有节点的值都大于它的根节点的值;
(3)其他的左右子树也分别为二叉查找树;
(4)二叉查找树是动态查找表,在查找的过程中可见添加和删除相应的元素,在这些操作中需要保持二叉查找树的以上性质。
2. 二叉查找树的定义
根据二叉查找树的要求,我们首先让BinaryNode实现Comparable接口。
// 树节点
class BinaryNode implements Comparable {
Integer element;
BinaryNode left;
BinaryNode right;
public BinaryNode{
}
public BinaryNode(Integer element, BinaryNode left, BinaryNode right) {
this.element = element;
this.left = left;
this.right = right;
}
@Override
public int compareTo(@NonNull Object o) {
return this.element - (Integer) o;
}
}
下面我们完成对BinarySearchTree的定义(只定义关键轮廓,具体接口后续进行分析)。
public class BinarySearchTree {
//定义树的根节点
BinaryNode root;
public BinarySearchTree() {
this.root = null;
}
public void makeEmpty() {
this.root = null;
}
public boolean isEmpty() {
return this.root == null;
}
// 判断是否包含某个元素
public boolean contains(Integer x) {
//TODO:后续讲解
return false;
}
// 查找最小值
public BinaryNode findMin(){
//TODO:后续讲解
return null;
}
// 查找最大值
public BinaryNode findMax(){
//TODO:后续讲解
return null;
}
// 按照顺序插入值
public void insert(Integer x){
//TODO:后续讲解
}
// 删除某个值
public void remove(Integer x){
//TODO:后续讲解
}
// 打印树
public void printTree(){
//TODO:后续讲解
}
}
3. contaions操作
如果在树T中包含项X的节点,那么该操作返回true,否则返回false。
树的结构使得这种操作变得非常简单,如果T为空集,直接返回false;否则我们就对T的左子树或右子树进行递归查找,直到找到该项X。
代码实现如下:
/**
* 是否包含某个元素
* @param x 待查找对象
* @return 查找结果
*/
public boolean contains(Integer x) {
// 首次查找从根节点开始
return contains(x,root);
}
private boolean contains(Integer x, BinaryNode node) {
// 根节点为空的情况,不需要再查找
if (node == null) {
return false;
}
// 与当前节点进行比较
int compareResult = x.compareTo(node.element);
// 小于当前节点的值,就递归遍历左子树
if (compareResult < 0) {
return contains(x, node.left);
}
// 大于当前节点的值,就递归遍历右子树
else if (compareResult > 0) {
return contains(x, node.right);
}
// 等于当前节点值,直接返回
else {
return true;
}
}
4. 查找最小节点
从根开始并且只要有左子树就向左进行,终止点就是最小元素节点。
// 查找最小值
public BinaryNode findMin() {
return findMin(root);
}
private BinaryNode findMin(BinaryNode node) {
// 当前节点为null,直接返回null
if (node == null) {
return null;
}
// 不存在左子树,返回当前节点
if (node.left == null) {
return node;
}
// 递归遍历左子树
return findMin(node.left);
}
5. 查找最大节点
从根开始并且只要有右子树就向右进行,终止点就是最大元素节点。作为与findMin的对比,findMax方法我们抛弃了常用的递归,使用了常见的while循环来查找。
// 查找最大值
public BinaryNode findMax() {
return findMax(root);
}
private BinaryNode findMax(BinaryNode node) {
if (node != null) {
while (node.right != null) {
node = node.right;
}
}
return node;
}
6. insert操作
插入操作在概念上是简单的,为了将X插入树T中,我们像contains一样沿着树查找。
如果找到X,那么我们可以什么都不做,也可以做一些更新操作。
否则,就将X插入到遍历路径上的最后一个节点。(这个做法有待商榷)
代码实现如下:
public void insert(Integer x) {
root = insert(x, root);
}
// 返回的插入节点的根节点
private BinaryNode insert(Integer x, BinaryNode node) {
// 如果当前节点为null,新建节点返回
if (node == null) {
return new BinaryNode(x, null, null);
}
// 与当前节点比较
int compareResult = x.compareTo(node.element);
// 小于当前节点值,递归插入左子树,并将返回值设置为当前节点的left
if (compareResult < 0) {
node.left = insert(x, node.left);
}
// 大于当前节点值,递归插入右子树,并将返回值设置为当前节点的right
if (compareResult > 0) {
node.right = insert(x, node.right);
}
// 等于当前的值,不做任何处理
if (compareResult == 0) {
// do some update or do noting
}
return node;
}
7. 删除操作
正如许多数据结构一样,最难的操作是remove,一旦我们发现了要删除的元素,就要考虑几种可能的情况:
当待删除的节点为叶子节点时,直接删除。
当待删除节点只有一个儿子节点时,把儿子节点代替该节点的位置,然后删除该节点。
当待删除的节点有两个儿子节点时,一般的删除策略是用其右子树的最小的数据代替该节点的数据并递归删除那个节点(现在它是空的);因为右子树的最小节点不可能有左儿子,所以第二次Delete要容易。
// 删除某个值
public void remove(Integer x) {
remove(x, root);
}
private BinaryNode remove(Integer x, BinaryNode node) {
if (node == null) {
return null;
}
int compareResult = x.compareTo(node.element);
if (compareResult < 0) {
node.left = remove(x, node.left);
}
if (compareResult > 0) {
node.right = remove(x, node.right);
}
if (compareResult == 0) {
if (node.left != null && node.right != null) {
node.element = findMin(node.right).element;
node.right = remove(node.element, node.right);
} else {
node = (node.left != null) ? node.left : node.right;
}
}
return node;
}
8. 二叉查找树的局限
同样的数据,可以对应不同的二叉搜索树,如下:

二叉搜索树可能退化成链表,相应的,二叉搜索树的查找操作是和这棵树的高度相关的,而此时这颗树的高度就是这颗树的节点数n,同时二叉搜索树相应的算法全部退化成 O(n) 级别。
显然,说二叉搜索树的查找、插入、删除这三个操作都是O(lgn) 级别的,只是一个大概的估算,具体要和二叉搜索树的形状相关。但总的来说时间复杂度在o(logn)
到o(n)之间。
9. 简单总结
二叉搜索树的节点查询、构造和删除性能,与树的高度相关,如果二叉搜索树能够更“平衡”一些,避免了树结构向线性结构的倾斜,则能够显著降低时间复杂度。二叉搜索树的存储方面,相对于线性结构只需要保存元素值,树中节点需要额外的空间保存节点之间的父子关系,所以在存储消耗上要高于线性结构。
【数据结构】什么是二叉查找树(BST)的更多相关文章
- 查找系列合集-二叉查找树BST
一. 二叉树 1. 什么是二叉树? 在计算机科学中,二叉树是每个结点最多有两个子树的树结构. 通常子树被称作“左子树”(left subtree)和“右子树”(right subtree). 二叉树常 ...
- [学习笔记] 二叉查找树/BST
平衡树前传之BST 二叉查找树(\(BST\)),是一个类似于堆的数据结构, 并且,它也是平衡树的基础. 因此,让我们来了解一下二叉查找树吧. (其实本篇是作为放在平衡树前的前置知识的,但为了避免重复 ...
- 二叉查找树(BST)
二叉查找树(BST):使用中序遍历可以得到一个有序的序列
- 二叉查找树BST 模板
二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东 ...
- 【查找结构 2】二叉查找树 [BST]
当所有的静态查找结构添加和删除一个数据的时候,整个结构都需要重建.这对于常常需要在查找过程中动态改变数据而言,是灾难性的.因此人们就必须去寻找高效的动态查找结构,我们在这讨论一个非常常用的动态查找树— ...
- 数据结构☞二叉搜索树BST
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...
- 数据结构-自平衡二叉查找树(AVL)详解
介绍: 在计算机科学中,AVL树是最先发明的自平衡二叉查找树. 在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树. 查找.插入和删除在平均和最坏情况下都是O(log n).增 ...
- 二叉查找树(BST)的实现
一.二叉树介绍 二叉查找树(Binary Search Tree,BST),又称二叉排序树,也称二叉搜索树,它或者是一颗空树,或者具有如下性质的树:若它的左子树不为空,则左子树上所有节点的值都小于根节 ...
- K:二叉查找树(BST)
相关介绍: 二叉查找树(英语:Binary Search Tree),也称二叉搜索树.有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tre ...
- 3.2 符号表之二叉查找树BST
一.插入和查找 1.二叉查找树(Binary Search Tree)是一棵二叉树,并且每个结点都含有一个Comparable的键,保证每个结点的键都大于其左子树中任意结点的键而小于其右子树的任意结点 ...
随机推荐
- 历史上的今天接口api
ip地址查询 www.ipip5.com 为大家提供历史上的今天接口api,提供txt和json两种返回格式. 1.txt文本格式 http://www.ipip5.com/today/api.p ...
- Linux服务器部署.Net Core笔记:一、开启ssh服务
开启ssh服务需要root权限,先用root账户登陆系统 在安装ssh前我们先更新一下yum:yum update 先检查有没有安装ssh服务:rpm -qa | grep ssh 如果没有安装ssh ...
- NPOI 工作簿一般设置
HSSFWorkbook workbook = new HSSFWorkbook(); //声明一个空白的工作簿,也可以将已有文件转化为文件流作为参数声明一个工作簿,这样这个工作簿里就会有已有文件中的 ...
- CAD绘图效率低?教你4个CAD绘图技巧,绘图效率提升十倍
CAD绘图一直是一个谜一样的存在,说它简单吧,很多人都无法完全精通,说它难吧,很多人也都自学成才了. 如何学好CAD绘图是个难题,但是老话说的好,只要思想不滑坡,办法总比困难多,掌握以下这些CAD绘图 ...
- 2.Redux学习2----redux-thunk
UI组件:只展示UI,不处理业务逻辑,又称傻瓜组件,因为只需要展示UI,没有状态,我们通常用函数组件(无状态组件)作为UI组件 容器父组件:只处理业务逻辑,不展示UI,又称聪明组件 redux-thu ...
- 爬取b站互动视频信息
首先分辨视频是不是互动视频可以看 https://api.bilibili.com/x/player.so?id=cid:1&aid=89017 这个api返回的xml中的 <inter ...
- 记druid 在配置中心下的一个大坑: cpu 达到 100%
把我们的dubbo 应用移步到配置中心上去之后,发现我们的应用过一段时间就会出现cpu 100%的情况 (大概是12个小时),一开始cpu占用是2-5% 的样子,什么都没做,后面竟然用尽了cpu.. ...
- 计算几何 val.1
目录 计算几何 val.1 向量的点积 向量的叉积 一种奇怪的三角剖分求面积 凸包 点绕点旋转 后记 计算几何 val.1 本文并不是入门文章,供有高中数学基础的阅读 主要写一些重要的点和注意事项吧 ...
- 【每天一题】LeetCode 0028. 字符串匹配
开源地址:https://github.com/jiauzhang/algorithms 题目描述 * https://leetcode-cn.com/problems/implement-strst ...
- (转)LSTM神经网络介绍
原文链接:http://www.atyun.com/16821.html 扩展阅读: https://machinelearningmastery.com/time-series-prediction ...