二叉查找树定义

二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;
  4. 没有键值相等的节点。

二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为O(log n)。

三层二叉查找树

二叉查找树的操作主要是运用的递归的思想,可操作的Object类必须继承了Comparable接口,个人实现查找树主要是参考了《数据结构与算法分析》这本书。因为遍历涉及到三种遍历方式,所以届时单独开一篇。

树的结点定义

 private static class BinaryNode<T>{
BinaryNode(T theElement) {
this(theElement,null,null);
}
BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt) {
element=theElement;
left=lt;
right=rt;
}
T element;//根节点
BinaryNode<T> left;//左子树
BinaryNode<T> right;//右子树
}

contains方法

 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;
}
}

contains方法主要是查找当前二叉树是否还有某个节点,利用了comparaTo方法递归调用。

findMin()与findMax()方法

 private BinaryNode<T> findMin(BinaryNode<T> t){
//非递归写法
if(t!=null)
while(t.left!=null)
t=t.left;
return t;
//递归写法
/*if(t==null)
return null;
else if (t.left==null) {
return t;
}
return findMin(t.left);*/
}

findMin与findMax方法类似,这里只列出一种即可。然后仍有两种方法解决此问题,一种为递归,一种非递归。

非递归方法就是采用了while循坏思想,直到找出最左的节点即可。

insert方法

 private BinaryNode<T> insert(T x,BinaryNode<T> t){
if(t==null)//生成新的节点
return new BinaryNode<T>(x, null, null);
if(contains(x))//如果二叉树中已经有x元素,则不进行任何操作
return t;
else {
int compareResult=x.compareTo(root.element);
if(compareResult<0){
t.left=insert(x, t.left);
}
else {
t.right=insert(x, t.right);
}
return t;
}
}

remove方法

 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;
}

删除节点时需要考虑两种情况,一种为两个孩子的情况,一种为单个孩子的情况。

如图为删除5节点为单个孩子情况

此图是删除3节点两个孩子的情况,具体做法是找出该节点右子树中最小的节点替换当前删除的节点

全部的代码如下(暂缺遍历)

 package Tree;

 public class BinarySearchTree<T extends Comparable<? super T>> {
private static class BinaryNode<T>{
BinaryNode(T theElement) {
this(theElement,null,null);
}
BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt) {
element=theElement;
left=lt;
right=rt;
}
T element;//根节点
BinaryNode<T> left;//左子树
BinaryNode<T> right;//右子树
}
private BinaryNode<T> root;//定义根节点
public BinarySearchTree() {
root=null;
}
public void makeEmpty(){
root=null;
}
public boolean isEmpty(){
return root==null;
}
public boolean contains(T x){
return contains(x,root);
}
public T findMin() throws Exception{
if(isEmpty())
throw new Exception();
return findMin(root).element;
}
public T findMax() throws Exception{
if(isEmpty())
throw new Exception();
return findMax(root).element;
}
public void insert(T x){
root=insert(x,root);
}
public void remove(T x){
root=remove(x,root);
}
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;
}
}
private BinaryNode<T> findMin(BinaryNode<T> t){
//非递归写法
if(t!=null)
while(t.left!=null)
t=t.left;
return t;
//递归写法
/*if(t==null)
return null;
else if (t.left==null) {
return t;
}
return findMin(t.left);*/
}
private BinaryNode<T> findMax(BinaryNode<T> t){
if(t!=null)
while(t.right!=null)
t=t.right;
return t;
}
private BinaryNode<T> insert(T x,BinaryNode<T> t){
if(t==null)//生成新的节点
return new BinaryNode<T>(x, null, null);
if(contains(x))//如果二叉树中已经有x元素,则不进行任何操作
return t;
else {
int compareResult=x.compareTo(root.element);
if(compareResult<0){
t.left=insert(x, t.left);
}
else {
t.right=insert(x, t.right);
}
return t;
}
}
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;
} }

也可访问我的gihub数据结构的部分,暂时内容较少。

JAVA数据结构--二叉查找树的更多相关文章

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

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

  2. Java数据结构和算法(二)树的基本操作

    Java数据结构和算法(二)树的基本操作 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 一.树的遍历 二叉树遍历分为:前序遍 ...

  3. 数据结构:JAVA实现二叉查找树

    数据结构:JAVA实现二叉查找树 写在前面 二叉查找树(搜索树)是一种能将链表插入的灵活性与有序数组查找的高效性结合在一起的一种数据结构. 观察二叉查找树,我们发现任何一个节点大于左子节点且小于其右子 ...

  4. 数据结构------------------二叉查找树(BST)的java实现

    数据结构------------------二叉查找树(BST)的java实现 二叉查找树(BST)是一种能够将链表插入的灵活性和有序数组查找的高效性相结合的一种数据结构.它的定义如下: 二叉查找树是 ...

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

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

  6. Java数据结构和算法(五)二叉排序树(BST)

    Java数据结构和算法(五)二叉排序树(BST) 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉排序树(Binary S ...

  7. Java数据结构和算法(二)顺序存储的树结构

    Java数据结构和算法(二)顺序存储的树结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉树也可以用数组存储,可以和完 ...

  8. 一文掌握关于Java数据结构所有知识点(欢迎一起完善)

    在我们学习Java的时候,很多人会面临我不知道继续学什么或者面试会问什么的尴尬情况(我本人之前就很迷茫).所以,我决定通过这个开源平台来帮助一些有需要的人,通过下面的内容,你会掌握系统的Java学习以 ...

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

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

随机推荐

  1. 运行jupyter

    在mac 命令行中输入 jupyter notebook 即可 https://www.datacamp.com/community/tutorials/tutorial-jupyter-notebo ...

  2. class Qstring has no member named to Ascii

    人家修改了.真的没有toAscii了.不过可以用toLatin1或者qPrintable()

  3. Red Hat 6.5 网络yum源的配置

    第一次接触Linux系统,用虚拟机安装了一个rad hat6.5版本64位的,傻瓜式安装.安装好之后简单的写了一个C代码,进行gcc编译的时候,提示没有该命令,上网查找了一下说没有安装gcc编译器,用 ...

  4. Oracle——约束

    NOT NULLUNIQUE PRIMARY KEYFOREIGN KEYCHECK 如果不指定约束名 ,Oracle server 自动按照 SYS_Cn 的格式指定约束名 --指定约束名 CREA ...

  5. POC索引

    最近在看窗口函数,接触到了POC索引,所以借此机会好好研究一下索引. 一般支持窗口函数的索引指南都遵循POC的概念,也就是Partitioning(分区).Ordering(排序)和Covering( ...

  6. UVALive 7752 Free Figurines (瞎搞)

    题意:给定 n 个盒子,然后告诉你每个盒子在哪个盒子里,数值越大,盒子越大,给定你初态,和末态,问你最少要几步能完成,只有两种操作,一种是把一个盒子连同里面的小盒子放到一个空盒子里,另一种是把一个堆盒 ...

  7. 特征工程 vs. 特征提取

    “特征工程”这个华丽的术语,它以尽可能容易地使模型达到良好性能的方式,来确保你的预测因子被编码到模型中.例如,如果你有一个日期字段作为一个预测因子,并且它在周末与平日的响应上有着很大的不同,那么以这种 ...

  8. java IO其他流

    1.内存操作流,ByteArrayInputStream和 ByteArrayOutputStream 案例:将小写转化为大写 /* * 内存操作流,将大写字母转化为小写字母(ByteArrayInp ...

  9. OpenCV实现均值哈希

    总共分三步:压缩,灰度化,均值化,求哈希值. 1.压缩 void secondMethod(char* filename, char* savename) { //const char* filena ...

  10. 敏捷软件开发:原则、模式与实践——第9章 OCP:开放-封闭原则

    第9章 OCP:开放-封闭原则 软件实体(类.模块.函数等)应该是可以扩展的,但是不可修改. 9.1 OCP概述 遵循开放-封闭原则设计出的模块具有两个主要特征: (1)对于扩展是开放的(open f ...