Java数据结构之二叉搜索树

原创 2016年08月30日 18:56:19

Java数据结构之二叉搜索树

1、二叉搜索树组成

二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是一颗具有如下特性的非空二叉树,需要满足一下三个条件:
(1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字;
(2)若它的右子树非空,则右子树上所有结点的关键字均大于(可以等于)根结点的关键字。
(3)左子树右子树本身又各是一颗二叉搜索树
 在算法描述中,均以结点值的比较来代表其关键字的比较,因为若结点的值为类类型时,该类必须实现系统提供的java.lang.comparable接口并定义有compareTo成员方法,以便对对象进行比较。
二叉搜索树

2、二叉搜索树实现

对二叉搜索树的操作重要的有三个方法:1、插入一个结点;2、删除一个结点;3、查找是否存在一个结点;
该二叉搜索树是通过链式存储来实现的,首先定义结点:
//定义结点类型
class Node{
	Object obj;
	Node left;
	Node right;
	public Node(Object obj,Node left,Node right){
		this.obj=obj;
		this.left=left;
		this.right=right;
	}
}

  1、插入一个结点

在二叉搜索树上进行插入结点操作时,要保证二叉搜索树的性质不变,即插入操作后二叉搜索树必须是按照左子树、根结点和右子树有序的。对二叉搜索树进行插入的过程是:首先需要查找新结点的插入位置,然后再插入链接。查找插入位置从树根结点开始,若树根指针为空,则新结点就是树根结点;否则,若obj等于根结点,则表明具有obj的值结点已经存在,不允许进行插入位置,应返回false表示插入失败;若obj小于根节点,则沿着根结点的左指针在左子树上继续查找插入位置,若obj大于根结点,则沿着根的右指针在右子树上继续查找插入位置。依次按层向下查找,当查找到一个结点的左指针或者是右指针为空时,则这个空的指针位置就是obj新结点的插入位置;
在进行插入链接时,若原树为空,则将新结点指针赋给boot,该新节点就成为整个二叉搜索树的树根结点,否则将新节点赋给pt结点的左指针域或者是右指针域,作为该结点的左孩子或是右孩子。插入完成后返回true。具体实现代码如下:
	//插入一个元素,插入成功则返回true 失败则返回false
	@Override
	public boolean insert(Object obj) {
		Node rt=root,pt=null;
		while(rt!=null){
			pt=rt;//把上一个结点给记录上
			if((Integer)(rt.obj)>(Integer)obj){
				rt=rt.left;
			}else if((Integer)(rt.obj)<(Integer)obj){
				rt=rt.right;
			}else{
				return false;
			}
		}
		Node node=new Node(obj,null,null);//新建一个结点
		if(pt==null){
			root=node;
		}else if((Integer)(pt.obj)<(Integer)obj){
			pt.right=node;
		}else{
			pt.left=node;
		}
		return true;
	}

  2、查找一个结点

由于二叉搜索树的特殊性,查找过程可以表示为:若二叉搜索树为空,则表示查找失败,应返回null,否则,若obj等于当前树根结点的值,则表明查找成功,应返回结点的完整值,若obj小于当前树根结点的值,则继续同右子树的根结点比较。通过树根沿着左孩子或右孩子逐层向下比较,每比较一次,下移一层,当查找到取值为obj的结点时,表明查找成功,应返回该结点的值;或者查找到空指针值,表明查找失败,应返回null。实现代码如下:
	//查找一个元素  找到则会返回该元素,找不到不会有任何返回
	@Override
	public Object find(Object obj) {
		if(root==null) return null;
		Node rt=root;
		while(rt!=null){
			if((Integer)(rt.obj)>(Integer)obj){
				rt=rt.left;
			}else if((Integer)(rt.obj)<(Integer)obj){
				rt=rt.right;
			}else{
				return rt.obj;
			}
		}
		return null;
	}

 3、删除一个结点

从二叉搜索树上删除结点(元素),它可能删除的是叶子结点,也可能删除的是分支结点,删除分支结点时,就破坏了原有结点之间的链接关系,需要重新修改指针,使得删除后仍为一颗二叉搜索树。
1、删除叶子结点
此种删除操作很简单,只要将其双亲结点链接到它的指针去掉即可。
2、删除单支结点
这种删除操作也比较简单,因为该结点只有左子树或右子树一支,也就是说,其伙计只有左孩子或右孩子一个。删除该节点时,只要将唯一的一个后继指针链接到它所在的链接位置即可。
3、删除双支结点
这种删除比较复杂,因为待删除的结点有两个后继指针,需要妥善处理,删除这种结点的一种方法是:首先将它的中序前驱的赋值给该结点的值域,然后再删除它的中序前驱结点,因它的中序前驱结点的右指针为空,所以只要把中序前驱结点的左指针连接到中序前驱结点所在的链接位置即可。
实现代码如下:
	//从二叉搜索树中删除一个结点,分为三类
	//1、删除叶子结点;2、删除单支结点;3、删除双支结点
	@Override
	public boolean delete(Object obj) {
		//从二叉搜索树中删除等于给定值的obj的结点,成功则返回true,失败则返回false
		if(root==null){
			return false;
		}
		Node rt=root,pt=null;
		while(rt!=null){
			if((Integer)(rt.obj)==(Integer)obj){
				break;
			}else if((Integer)(rt.obj)>(Integer)obj){
				pt=rt;
				rt=rt.left;
			}else {
				pt=rt;
				rt=rt.right;
			}
		}
		if(rt==null) return false;//如果没找到该元素的话,返回空
		//分三种情况删除以查找到的结点 rt
		//删除叶子结点
		if(rt.left==null && rt.right==null){//删除叶子结点,直接删除操作
			if(rt==root) root=null;
			else if(pt.left==rt) pt.left=null;
			else pt.right=null;
		}
		//删除rt结点为单分支时的情况处理
		else if(rt.left==null || rt.right==null){
			if(rt==root){//先处理rt是根节点的情况
				if(rt.left==null) root=rt.right;
				else root=rt.left;
			}else if(pt.left==rt && rt.left==null){//处理单支结点,分为四种情况
				pt.left=rt.right;
			}else if(pt.left==rt && rt.right==null){
				pt.left=rt.left;
			}else if(pt.right==rt && rt.left==null){
				pt.right=rt.right;
			}else if(pt.right==rt && rt.right==null){
				pt.right=rt.left;
			}else ;
		}
		//处理都有双子树的结点
		else if(rt.left!=null && rt.right!=null){
			Node s1=rt,s2=rt.left;
			while(s2.right!=null){
				s1=s2;s2=s2.right;
			}
			rt.obj=s2.obj;//把中序前驱结点s2的值赋给rt结点
			if(s1==rt){//对rt的中序前驱结点就是rt的左孩子的情况进行处理
				rt.left=s2.left;
			}else{//对rt的中序前驱结点为其左海子的右子树的情况来处理
				s1.right=s2.left;
			}
		}
		return true;//删除成功后返回
	}
输出搜索二叉树代码如下:
	//输出二叉树
	public void inOrderTravers(Node node){
		if(node!=null){
			inOrderTravers(node.left);
			System.out.print(node.obj+" ");
			inOrderTravers(node.right);
		}else;
	}








数据结构基础(17) --二叉查找树的设计与实现

二叉排序树的特征 二叉排序树或者是一棵空树,或者是具有如下特性的二叉树:     1.每一元素都有一个键值, 而且不允许重复;     2.若它的左子树不空,则左子树上所有结点的值均小于根结点的...

二叉排序树(二叉搜索树)

题目大意:现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。 九度OJlianb...

java数据结构之二叉搜索树

package com.jimmy.impl; import com.jimmy.BinaryTreeInterface; //继承二叉树,泛型T必须是Comparable的 ...

跟着《算法导论》学习——数据结构之二叉搜索树

读前声明:本人所写帖子主要为了记录本人学习的一个过程,无他想法,由于内容比较肤浅,如有雷同,非常正常!!! 本文内容: 本文主要是参考《算法导论》这本书,完成部分算法编写,可能编程习惯或者风格...

数据结构之二叉搜索树c++ 简单版

//二叉搜索树,简单的来讲就是一种左孩子小于双亲节点和右孩子大于双亲节点的二叉树。 #include "stdafx.h" #include #include using namespace ...

python 数据结构之二叉搜索树

二叉搜索树定义一颗二叉搜索树是以二叉树来组织的,每个节点除了 Key 还包括 左孩子, 右孩子, 父节点 等信息. BST满足限制条件: 对于任意节点的X,他的 左子树中关键字最大值=X.key 这个...

数据结构之二叉搜索树(BinarySearchTree)

一。定义:二叉搜索树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质...

数据结构之二叉搜索树

package com.zhiru; import java.util.Random; /* * 二查搜索树 * 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 任意节...

数据结构之二叉搜索树和二叉平衡树学习笔记

二叉搜索树(Binary Search Tree)具有下列性质的二叉树被称为二叉搜索树:(1)、若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值; (2)、若它的右子树不为空,则右子树上...

数据结构与算法分析(Java语言描述)(20)—— 二叉搜索树指定key的前驱、后继

前驱// -------------------------------------------------------------------- // 查找 key 的前驱 publi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java数据结构之二叉搜索树
举报原因:
原因补充:

(最多只允许输入30个字)