一、二叉查找树定义

二叉树每个节点都不能有多于两个的儿子。二叉查找树是特殊的二叉树,对于树中的每个节点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. 普通项目——>maven项目——>SSM(一)

    首先应该明白,SSM是什么? SSM指的是Spring+SpringMVC+MyBatis Spring Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体 ...

  2. jmeter应用之批量插入数据

    上一篇讲到如何在jmeter中配置并连接使用mysql数据库,这一节主要是讲数据库连接的简单应用——批量插入数据 总体步骤如下: 1)新建线程组和添加JDBC Connection Configura ...

  3. 解决MySql忘记密码

    描述:忘记了mysql的登录密码,无法登录的情况下该怎么办? 环境:CentOS 7,数据库:mysql 5.7 1.停止数据库(先查看mysql服务是否运行) # ps -ef | -i grep ...

  4. I-最短的名字

    在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab. 名字这么长,叫全名显然起来很不方便.所以村民之间一般只叫名字的前缀.比如叫’aaaaa’的时候可以只叫’a ...

  5. css兼容问题收集+部分效果收集+css重置

    1.居中问题 div里的内容,IE默认为居中,而FF默认为左对齐,可以尝试增加代码margin: 0 auto; 2.高度问题 两上下排列或嵌套的div,上面的div设置高度(height),如果di ...

  6. HTML第一课(前期知识准备)

    在正式的学习之前,我们先了解一些前端方面的常识. 一.前端是做什么? 如果有认真看过我写的预备程序员不得不知道的事儿这篇文章的同学应该清楚,前端的工作在整个项目开发中处于代码编写阶段,主要是用来做界面 ...

  7. js函数调用的几种方法

    js的函数调用会免费奉送两个而外的参数就是 this 和 arguments .arguments是参数组,他并不是一个真实的数组,但是可以使用.length方法获得长度. 书上有说4中调用方式: 方 ...

  8. mesg - 调节用户终端的写访问权

    总览 (SYNOPSIS) mesg [y|n] 描述 (DESCRIPTION) Mesg 控制 其他用户 对 你的终端 的 访问能力. 典型用途 是 允许 或 禁止 其他用户向 你的终端 输出 数 ...

  9. 费用流+SPFA ||【模板】最小费用最大流

    题面:[模板]最小费用最大流 代码: #include<cstdio> #include<cstring> #include<iostream> #include& ...

  10. mybatis返回自增主键问题踩坑

    1 <insert id="insert" keyProperty="id" useGeneratedKeys="true"
 par ...