您的位置:首页 > 编程语言 > Java开发

二叉查找树--查找、删除、插入(Java实现)

2017-04-26 10:39 666 查看
文章,未经博主允许不得转载。

目录(?)
下篇:平衡二叉树

http://blog.csdn.net/kiritor/article/details/8892648

二叉查找树

二叉查找树(Binary Search Tree),或者是一颗空树,或者是具有下列性质的二叉树:

1、若它的左子树不空,则其左子树上的所有结点的值均小于它根结点的值;

2、若它的右子树不空,则其右子树上的所有结点的值均大于它根结点的值;

3、它的左、右子树也分别为二叉查找树。



二叉查找树是基于二叉树的,其结点数据结构定义为如下:

[java] view
plain copy

/**结点数据结构*/

static class BinaryNode<T>

{

T data;

BinaryNode<T> left;

BinaryNode<T> right;

public BinaryNode(T data) {

this(data,null,null);

}

public BinaryNode( T data, BinaryNode<T> left, BinaryNode<T> right) {

this.data =data;

this.left = left;

this.right =right;

}

public BinaryNode()

{

data =null;

this.left = left;

this.right =right;

}

}

现在明白了什么是二叉查找树,那么二叉查找书的基本操作又是如何来实现的呢?

查找操作

在二叉查找树中查找x的过程如下:

1、若二叉树是空树,则查找失败。

2、若x等于根结点的数据,则查找成功,否则。

3、若x小于根结点的数据,则递归查找其左子树,否则。

4、递归查找其右子树。

根据上述的步骤,写出其查找操作的代码:

[java] view
plain copy

/**查找指定的元素,默认从

* 根结点出开始查询*/

public boolean contains(T t)

{

return contains(t, rootTree);

}

/**从某个结点出开始查找元素*/

public boolean contains(T t, BinaryNode<T> node)

{

if(node==null)

return false;//结点为空,查找失败

int result = t.compareTo(node.data);

if(result>0)

return contains(t,node.right);//递归查询右子树

else if(result<0)

return contains(t, node.left);//递归查询左子树

else

return true;

}

/**

这里我提供一个对二叉树最大值

最小值的搜索*/

/**找到二叉查找树中的最小值*/

public T findMin()

{

if(isEmpty())

{

System.out.println("二叉树为空");

return null;

}else

return findMin(rootTree).data;

}

/**找到二叉查找树中的最大值*/

public T findMax()

{

if(isEmpty())

{

System.out.println("二叉树为空");

return null;

}else

return findMax(rootTree).data;

}

/**查询出最小元素所在的结点*/

public BinaryNode<T> findMin(BinaryNode<T> node)

{

if(node==null)

return null;

else if(node.left==null)

return node;

return findMin(node.left);//递归查找

}

/**查询出最大元素所在的结点*/

public BinaryNode<T> findMax(BinaryNode<T> node)

{

if(node!=null)

{

while(node.right!=null)

node=node.right;

}

return node;

}

插入操作

二叉树查找树b插入操作x的过程如下:

1、若b是空树,则直接将插入的结点作为根结点插入。

2、x等于b的根结点的数据的值,则直接返回,否则。

3、若x小于b的根结点的数据的值,则将x要插入的结点的位置改变为b的左子树,否则。

4、将x要出入的结点的位置改变为b的右子树。

代码实现如下:

[java] view
plain copy

/**插入元素*/

public void insert(T t)

{

rootTree = insert(t, rootTree);

}

/**在某个位置开始判断插入元素*/

public BinaryNode<T> insert(T t,BinaryNode<T> node)

{

if(node==null)

{

//新构造一个二叉查找树

return new BinaryNode<T>(t, null, null);

}

int result = t.compareTo(node.data);

if(result<0)

node.left= insert(t,node.left);

else if(result>0)

node.right= insert(t,node.right);

else

;//doNothing

return node;

}

删除操作

对于二叉查找树的删除操作(这里根据值删除,而非结点)分三种情况:

不过在此之前,我们应该确保根据给定的值找到了要删除的结点,如若没找到该结点

不会执行删除操作!

下面三种情况假设已经找到了要删除的结点。

1、如果结点为叶子结点(没有左、右子树),此时删除该结点不会玻化树的结构

直接删除即可,并修改其父结点指向它的引用为null.如下图:



2、如果其结点只包含左子树,或者右子树的话,此时直接删除该结点,并将其左子树

或者右子树设置为其父结点的左子树或者右子树即可,此操作不会破坏树结构。



3、 当结点的左右子树都不空的时候,一般的删除策略是用其右子树的最小数据

(容易找到)代替要删除的结点数据并递归删除该结点(此时为null),因为

右子树的最小结点不可能有左孩子,所以第二次删除较为容易。

z的左子树和右子树均不空。找到z的后继y,因为y一定没有左子树,所以可以删除y,

并让y的父亲节点成为y的右子树的父亲节点,并用y的值代替z的值.如图:



删除操作源码:

[java] view
plain copy

/**删除元素*/

public void remove(T t)

{

rootTree = remove(t,rootTree);

} /**在某个位置开始判断删除某个结点*/

public BinaryNode<T> remove(T t,BinaryNode<T> node)

{

if(node == null)

return node;//没有找到,doNothing

int result = t.compareTo(node.data);

if(result>0)

node.right = remove(t,node.right);

else if(result<0)

node.left = remove(t,node.left);

else if(node.left!=null&&node.right!=null)

{

node.data = findMin(node.right).data;

node.right = remove(node.data,node.right);

}

else

node = (node.left!=null)?node.left:node.right;

return node;

}

完整源码

[java] view
plain copy

<p></p><pre name="code" class="java">package com.kiritor;

/**

* Java实现二叉查找树

* @author Kiritor

* @param <T>*/

public class BinarySearchTree<T extends Comparable<? super T>> {

/**结点数据结构*/

static class BinaryNode<T>

{

T data;

BinaryNode<T> left;

BinaryNode<T> right;

public BinaryNode(T data) {

this(data,null,null);

}

public BinaryNode( T data, BinaryNode<T> left, BinaryNode<T> right) {

this.data =data;

this.left = left;

this.right =right;

}

public BinaryNode()

{

data =null;

this.left = left;

this.right =right;

}

}

private BinaryNode<T> rootTree;

/**构造一颗空的二叉查找树*/

public BinarySearchTree()

{

rootTree = null;

}

/**清空二叉查找树*/

public void clear()

{

rootTree = null;

}

/**判断是否为空*/

public boolean isEmpty()

{

return rootTree == null;

}

/**查找指定的元素,默认从

* 根结点出开始查询*/

public boolean contains(T t)

{

return contains(t, rootTree);

}

/**找到二叉查找树中的最小值*/

public T findMin()

{

if(isEmpty())

{

System.out.println("二叉树为空");

return null;

}else

return findMin(rootTree).data;

}

/**找到二叉查找树中的最大值*/

public T findMax()

{

if(isEmpty())

{

System.out.println("二叉树为空");

return null;

}else

return findMax(rootTree).data;

}

/**插入元素*/

public void insert(T t)

{

rootTree = insert(t, rootTree);

}

/**删除元素*/

public void remove(T t)

{

rootTree = remove(t,rootTree);

}

/**打印二叉查找树*/

public void printTree()

{

}

/**从某个结点出开始查找元素*/

public boolean contains(T t, BinaryNode<T> node)

{

if(node==null)

return false;

int result = t.compareTo(node.data);

if(result>0)

return contains(t,node.right);

else if(result<0)

return contains(t, node.left);

else

return true;

}

/**查询出最小元素所在的结点*/

public BinaryNode<T> findMin(BinaryNode<T> node)

{

if(node==null)

return null;

else if(node.left==null)

return node;

return findMin(node.left);//递归查找

}

/**查询出最大元素所在的结点*/

public BinaryNode<T> findMax(BinaryNode<T> node)

{

if(node!=null)

{

while(node.right!=null)

node=node.right;

}

return node;

}

/**在某个位置开始判断插入元素*/

public BinaryNode<T> insert(T t,BinaryNode<T> node)

{

if(node==null)

{

//新构造一个二叉查找树

return new BinaryNode<T>(t, null, null);

}

int result = t.compareTo(node.data);

if(result<0)

node.left= insert(t,node.left);

else if(result>0)

node.right= insert(t,node.right);

else

;//doNothing

return node;

}

/**在某个位置开始判断删除某个结点*/

public BinaryNode<T> remove(T t,BinaryNode<T> node)

{

if(node == null)

return node;//没有找到,doNothing

int result = t.compareTo(node.data);

if(result>0)

node.right = remove(t,node.right);

else if(result<0)

node.left = remove(t,node.left);

else if(node.left!=null&&node.right!=null)

{

node.data = findMin(node.right).data;

node.right = remove(node.data,node.right);

}

else

node = (node.left!=null)?node.left:node.right;

return node;

}

public BinaryNode<Integer> init()

{

BinaryNode<Integer> node3 = new BinaryNode<Integer>(3);

BinaryNode<Integer> node1 = new BinaryNode<Integer>(1);

BinaryNode<Integer> node4 = new BinaryNode<Integer>(4,node3,null);

BinaryNode<Integer> node2 = new BinaryNode<Integer>(2,node1,node4);

BinaryNode<Integer> node8 = new BinaryNode<Integer>(8);

BinaryNode<Integer> root = new BinaryNode<Integer>(6,node2,node8);

return root;

}

public void preOrder(BinaryNode node) {

if (node != null) {

System.out.print(node.data);

preOrder(node.left);

preOrder(node.right);

}

}

/*简单测试*/

public static void main(String[] args) {

BinarySearchTree searchTree = new BinarySearchTree<>();

BinaryNode<Integer> node= searchTree.init();

searchTree.rootTree=node;

searchTree.preOrder(searchTree.rootTree);

searchTree.remove(4);

searchTree.preOrder(searchTree.rootTree);

}

} </pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: