JAVA数据结构--二叉查找树
二叉查找树定义
二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点。
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为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数据结构--二叉查找树的更多相关文章
- Java数据结构和算法(四)赫夫曼树
Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...
- Java数据结构和算法(二)树的基本操作
Java数据结构和算法(二)树的基本操作 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 一.树的遍历 二叉树遍历分为:前序遍 ...
- 数据结构:JAVA实现二叉查找树
数据结构:JAVA实现二叉查找树 写在前面 二叉查找树(搜索树)是一种能将链表插入的灵活性与有序数组查找的高效性结合在一起的一种数据结构. 观察二叉查找树,我们发现任何一个节点大于左子节点且小于其右子 ...
- 数据结构------------------二叉查找树(BST)的java实现
数据结构------------------二叉查找树(BST)的java实现 二叉查找树(BST)是一种能够将链表插入的灵活性和有序数组查找的高效性相结合的一种数据结构.它的定义如下: 二叉查找树是 ...
- Java数据结构和算法(七)B+ 树
Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...
- Java数据结构和算法(五)二叉排序树(BST)
Java数据结构和算法(五)二叉排序树(BST) 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉排序树(Binary S ...
- Java数据结构和算法(二)顺序存储的树结构
Java数据结构和算法(二)顺序存储的树结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉树也可以用数组存储,可以和完 ...
- 一文掌握关于Java数据结构所有知识点(欢迎一起完善)
在我们学习Java的时候,很多人会面临我不知道继续学什么或者面试会问什么的尴尬情况(我本人之前就很迷茫).所以,我决定通过这个开源平台来帮助一些有需要的人,通过下面的内容,你会掌握系统的Java学习以 ...
- java数据结构和算法06(红黑树)
这一篇我们来看看红黑树,首先说一下我啃红黑树的一点想法,刚开始的时候比较蒙,what?这到底是什么鬼啊?还有这种操作?有好久的时间我都缓不过来,直到我玩了两把王者之后回头一看,好像有点儿意思,所以有的 ...
随机推荐
- 8、技术分析fastJson使用
一.导入包 二.使用 package com.itheima.test; import java.util.ArrayList; import java.util.List; import org.j ...
- N-Gram的数据结构
ARPA的n-gram语法如下: [html] view plaincopyprint? \data\ ngram 1=64000 ngram 2=522530 ngram 3=173445 \1-g ...
- 实践作业3:白盒测试----总结与反思DAY12.
---恢复内容开始--- 阶段一:熟悉白盒测试方法 负责人:刘思佳 工作质量评价:用例设计详细,考虑到白盒测试基于代码,所以尽可能地覆盖更多的白盒测试方法,对系统可能存在的缺陷就更容易了解.对管理员和 ...
- [GO]json解析到结构体
package main import ( "encoding/json" "fmt" ) type IT struct { Company string `j ...
- Generated by NetworkManager、ubuntu DNS设置丢失(network-manager造成的情况)
方法一:去掉重启 方法二:卸载network-manager 实测网络不稳,经常掉线(kalinux2.0环境)
- Postman -- HTTP请求的Chrome插件
摘要 : Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件. 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网 ...
- JavaScript - this详解 (二)
用栗子说this Bug年年有,今年特别多 对于JavaScript这么灵活的语言来说,少了this怎么活! function 函数 this 对于没有实例化的function,我们称之为函数,即没有 ...
- linux 用户和组
每个用户拥有一个UID,操作系统实际使用的是用户ID,而非用户名 每个用户属于一个主组,而且属于一个或多个附属组 每个组有一个GroupID 每个进程以一个用户身份运行,并受该用户可访问的资源限制 每 ...
- 27款经典的CSS框架
利用 CSS 框架,可以简化你的工作,提高工作效率.CSS 框架是一系列 CSS 文件的集合体,包含了基本的元素重置,页面排版.网格布局.表单样式.通用规则等代码块.下面给你推荐了27款优秀的CSS框 ...
- [Erlang01] 使用catch与try catch避免嵌套nest_case
catch 如此好用,为什么官方还是推荐用try catch? 1. catch 的用法非常简单: catch case do_check(Test) of {ok,Result} -> do_ ...