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?这到底是什么鬼啊?还有这种操作?有好久的时间我都缓不过来,直到我玩了两把王者之后回头一看,好像有点儿意思,所以有的 ...
随机推荐
- A*搜索 概念
启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标.这样可以省略大量无畏的搜索路径,提到了效率.在启发式搜索中,对位置的估价是十分重要 ...
- Web实践—Rec 1
累计完成任务情况: 阶段内容 参与人 开会学习作业要求,取得共识 全体 注: 1."阶段内容"划斜线表示完成.2.采用倒序. 具体情况: 正式开展实践作业之前的说明: 按照之前达成 ...
- eclipse 按装lombok与注解说明
原文:http://www.cnblogs.com/ywqbj/p/5711691.html 一.安装lombok 1.下载 lombok-1.16.16.jar 包 我的下载完后放到:/root ...
- 马尔可夫决策过程MDP
1. 马尔可夫模型的几类子模型 马尔科夫链(Markov Chain),了解机器学习的也都知道隐马尔可夫模型(Hidden Markov Model,HMM).它们具有的一个共同性质就是马尔可夫性(无 ...
- react+webpack基础学习配置
最近学习react,公司的项目是使用create-react-app来搭建的,而我想重新使用node+mysql+react来搭建一个新的博客. 今天尝试从零开始搭建一个webpack+react项目 ...
- 在Arch gnome中安装一些软件
一. 在Arch gnome中添加ibus中文输入法 1. 安装ibus-libpinyin. sudo pacman -S ibus-libpinyin 如果系统之前没有安装ibus,则先通过pac ...
- elasticsearch常用JAVA API 实例
1.引入dependency <dependency> <groupId>org.springframework.data</groupId> <artifa ...
- C# xsd 验证 XML数据有效性 问题
使用XSD进行批量数据导入时生成的XML数据有效性这样的功能已经不是第一次做了,之前做的时候都没有碰到什么问题,这些天在开发中遇到了一个很头痛的问题就是无论XSD文件规则怎么写,验证都是通过的. 下面 ...
- C#操作系统计划任务
首先需要引用system32下的taskschd.dll 测试环境:win8+vs2012+.net4.0 /// <summary> /// 删除任务 /// </summary& ...
- CLR via C# 读书笔记-21.托管堆和垃圾回收
前言 近段时间工作需要用到了这块知识,遂加急补了一下基础,CLR中这一章节反复看了好多遍,得知一二,便记录下来,给自己做一个学习记录,也希望不对地方能够得到补充指点. 1,.托管代码和非托管代码的区别 ...