一、二叉查找树定义

二叉树每个节点都不能有多于两个的儿子。二叉查找树是特殊的二叉树,对于树中的每个节点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. 排列perm HYSBZ - 1072(状压dp/暴力)

    Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input ...

  2. 毛玻璃效果 css

    毛玻璃效果 <style> .container{ width: 287px; height: 285px; background-image: url(img/background.pn ...

  3. maven项目出现红叉

    现象:maven项目出现红叉,同时项目中没出现代码错误 解决方案: 可尝试在本地maven项目pom.xml中添加如下: <build> <plugins> <plugi ...

  4. mvvm实现一个简单的vue

    vue,基于mvvm模式下的一个前端框架 mvvm模式下简单的实现数据代理,数据劫持 1.是用Object.defineProperty 实现数据代理 2.使用发布订阅者模式,配合 Object.de ...

  5. Vue之路由跳转 传参 aixos 和cookie

    一.路由跳转 1.1 项目的初始化 vue create m-proj   >>>创建vue项目 精简vue项目的 views 视图   About(基本是删除的) Home.(可以 ...

  6. redis防止抢购商品超卖

    前言: redis不仅仅是单纯的缓存,它还有一些特殊的功能,在一些特殊场景上很好用. 本篇博文用来测试下使用redis来防止抢购商品超卖问题. 内容: 使用redis的list进行测试 思路是设置一个 ...

  7. vue + nginx部署404

    记录: vue项目打包放到服务器,使用nginx反向代理的时候路由页面刷新报404,因为刷新时,不存在路径对应的文件或文件夹,需要在nginx配置中添加代码: index index.html; tr ...

  8. Linux vim程序编辑器

    Tips: 在 vi 里面, [tab] 这个按钮所得到的结果与空格符所得到的结果是不一样的,特别强调一下! 一般模式 移动光标 30↓ 向下移动30行 40→ 向右移动40个字符 gg 移动到档案第 ...

  9. VB.net删除节点,数据库,文件

    Private Sub mnuDel_Click()'删除节点Dim sKey As String'Dim sFile As StringDim oFS As FileSystemObjectDim ...

  10. 1126. Eulerian Path (25)

    In graph theory, an Eulerian path is a path in a graph which visits every edge exactly once. Similar ...