一、二叉查找树定义

二叉树每个节点都不能有多于两个的儿子。二叉查找树是特殊的二叉树,对于树中的每个节点X,它的左子树中的所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项。

二叉查找树节点的定义:

private static class BinaryNode<T> {
T element; // 节点的值
BinaryNode<T> left; // 左子节点
BinaryNode<T> right; // 右子节点 public BinaryNode(T element) {
this(element, null, null);
} public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {
this.element = element;
this.left = left;
this.right = right;
}
}

二、树的遍历

树的三种遍历方式:前序遍历、中序遍历、后序遍历。这里的前中后是相对于根节点而言的:

  • 前序遍历:根节点->左子树->右子树
  • 中序遍历:左子树->根节点->右子树
  • 后序遍历:左子树->右子树->根节点

对于下面这样一棵树,不同的遍历方式结果如下:

前序遍历:ABDGHCEIF

private void preOrder(BinaryNode<T> root) {
if (root == null) {
return;
}
System.out.printf("%d ", root.element);
preOrder(root.left);
preOrder(root.right);
}

中序遍历:GDHBAEICF

private void inOrder(BinaryNode<T> root) {
if (root == null) {
return;
}
inOrder(root.left);
System.out.printf("%d ", root.element);
inOrder(root.right);
}

后序遍历:GHDBIEFCA

private void postOrder(BinaryNode<T> root) {
if (root == null) {
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.printf("%d ", root.element);
}

三、二叉查找树的基本操作

3.1 contains方法

/**
* 判断树t中是否存在含有项x的节点
*
* @param x 值
* @param t 以t为根节点的一棵树
* @return
*/
private boolean contains(T x, BinaryNode<T> t) {
if (t == null) {
return false;
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
return contains(x, t.left);
} else if (compareResult > 0) {
return contains(x, t.right);
} else {
return true;
}
} public boolean contains(T x) {
return contains(x, root);
}

3.2 find方法

/**
* 查找树t中值为x的节点
* @param x
* @param t
* @return
*/
private BinaryNode<T> find(T x, BinaryNode<T> t) {
if (t == null) {
return t;
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
return find(x, t.left);
} else if (compareResult > 0) {
return find(x, t.right);
} else {
return t;
}
} public BinaryNode<T> find(T x) {
return find(x, root);
}

3.3 最大值与最小值

查找树中最大值的节点

private BinaryNode<T> findMax(BinaryNode<T> t) {
if (t == null) {
return null;
}
while (t.right != null) {
t = t.right;
}
return t;
} public BinaryNode<T> findMax() {
return findMax(root);
}

查找树中最小值的节点

private BinaryNode<T> findMin(BinaryNode<T> t) {
if (t == null) {
return null;
}
while (t.left != null) {
t = t.left;
}
return t;
} public BinaryNode<T> findMin() {
return findMin(root);
}

3.4 insert方法

private BinaryNode<T> insert(T x, BinaryNode<T> t) {
if (t == null) {
return new BinaryNode<>(x, null, null);
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
t.left = insert(x, t.left);
} else if (compareResult > 0) {
t.right = insert(x, t.right);
} else {
// 出现重复值,忽略不处理
}
return t;
} public void insert(T x) {
root = insert(x, root);
}

3.5 remove方法

  • 如果需要删除的节点是叶节点,那么可以直接删除;
  • 如果节点有一个儿子,则让儿子节点取代该节点即可;
  • 如果节点有两个儿子,通常用其右子树的最小的数据代替该节点的数据并递归地删除那个节点。

    因为右子树的最小节点不可能有左儿子
public void remove(T x) {
root = remove(x, root);
} private BinaryNode<T> remove(T x, BinaryNode<T> t) {
if (t == null) {
return t;
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
t.left = remove(x, t.left);
} else if (compareResult > 0) {
t.right = remove(x, t.right);
} else if (t.left != null && t.right != null) {
// 用右子树的最小的数据代替该节点的数据并递归地删除这个节点
t.element = findMin(t.right).element;
t.right = remove(t.element, t.right);
} else {
// 只有一个儿子,直接用儿子代替该节点
t = (t.left != null) ? t.left : t.right;
}
return t;
}

Java数据结构与算法(4):二叉查找树的更多相关文章

  1. Java数据结构和算法(七)B+ 树

    Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...

  2. Java数据结构和算法(四)赫夫曼树

    Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...

  3. java数据结构和算法06(红黑树)

    这一篇我们来看看红黑树,首先说一下我啃红黑树的一点想法,刚开始的时候比较蒙,what?这到底是什么鬼啊?还有这种操作?有好久的时间我都缓不过来,直到我玩了两把王者之后回头一看,好像有点儿意思,所以有的 ...

  4. Java数据结构和算法

    首先,本人自学java,但是只学习了java的基础知识,所以想接下来学习一下数据结构和算法,但是找了很多教材,大部分写的好的都是用c语言实现的,虽然知道数据结构和算法,跟什么语言实现的没有关系,但是我 ...

  5. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  6. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  7. Java数据结构和算法(十四)——堆

    在Java数据结构和算法(五)——队列中我们介绍了优先级队列,优先级队列是一种抽象数据类型(ADT),它提供了删除最大(或最小)关键字值的数据项的方法,插入数据项的方法,优先级队列可以用有序数组来实现 ...

  8. Java数据结构和算法(九)——高级排序

    春晚好看吗?不存在的!!! 在Java数据结构和算法(三)——冒泡.选择.插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大 ...

  9. java数据结构与算法之栈(Stack)设计与实现

    本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...

随机推荐

  1. HTTP请求状态码为400时的原因

    2019-11-30 出现这个请求无效说明请求没有进入后台服务器里 原因: (1)前端提交的字段名称或者字段类型和后台的实体类不一样 或者前端提交的参数跟后台需要的参数个数不一致,导致无法封装 (2) ...

  2. [Python3] 002 Python3 中常用的命名规则

    目录 1. 什么可以用来命名? 1.1 老三样: 字母.数字.下划线 1.2 其他 2. 什么不能用来命名? Python3 中的"关键字" 3. 命名"小贴士" ...

  3. 创建React脚手架

    node版本10.14.2 下载地址 如果是其版本的话会出错 css-loader 会不兼容 主要是8.x的版本不兼容 npm install -g create-react-app 全局安装 cre ...

  4. How to attach multiple files in the Send Mail Task in SSIS

    Let’s say you need to create a SSIS package that creates 2 files and emails the files to someone. Yo ...

  5. MySQL插入emoji表情报错 SQLException: Incorrect string value 的两种解决方案

    摘抄自:https://blog.csdn.net/dmw412724/article/details/81119325 原因:mysql的UTF-8只支持三个字节的存储,而一般字符是三个字节,但是e ...

  6. P3951小凯的疑惑

    这是2017年提高组的第一题,是一个小学奥数题?听说很多大佬爆零了,我AC了,,, 这个题首先给出两个素数,问取任意个这两个素数之和不可以达到的最大的数是多少?拿到这个题首先很蒙,于是试了试样例,并没 ...

  7. gRPC go安装教程

    安装protobuf go get -u github.com/golang/protobuf/proto go get -u github.com/golang/protobuf/protoc-ge ...

  8. python3 pycurl 出现 TypeError: string argument expected, got 'bytes' 解决方案

    用pycurl请求指定链接并返回结果时出现 TypeError: string argument expected, got 'bytes'  错误 经过排查问题出现在使用StringIO的write ...

  9. 利用CSS的translate属性或利用CSS实现图片居中的效果

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. mongodb启动报错,child process failed, exited with error number 1

    error: child process failed, exited with error number 1 第一次安装mongodb,随后启动一般不会出现上面的错误,出现这种错误的原因一般是mon ...