http://blog.csdn.net/kiritor/article/details/8892648
二叉查找樹
二叉查找樹(Binary Search Tree),或者是一顆空樹,或者是具有下列性質的二叉樹:
1、若它的左子樹不空,則其左子樹上的所有結點的值均小於它根結點的值;
2、若它的右子樹不空,則其右子樹上的所有結點的值均大於它根結點的值;
3、它的左、右子樹也分別爲二叉查找樹。
二叉查找樹是基於二叉樹的,其結點數據結構定義爲如下:
-
-
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、遞歸查找其右子樹。
根據上述的步驟,寫出其查找操作的代碼:
-
-
-
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的右子樹。
代碼實現如下:
-
-
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
-
;
-
return node;
-
}
刪除操作
對於二叉查找樹的刪除操作(這裏根據值刪除,而非結點)分三種情況:
不過在此之前,我們應該確保根據給定的值找到了要刪除的結點,如若沒找到該結點
不會執行刪除操作!
下面三種情況假設已經找到了要刪除的結點。
1、如果結點爲葉子結點(沒有左、右子樹),此時刪除該結點不會玻化樹的結構
直接刪除即可,並修改其父結點指向它的引用爲null.如下圖:
2、如果其結點只包含左子樹,或者右子樹的話,此時直接刪除該結點,並將其左子樹
或者右子樹設置爲其父結點的左子樹或者右子樹即可,此操作不會破壞樹結構。
3、 當結點的左右子樹都不空的時候,一般的刪除策略是用其右子樹的最小數據
(容易找到)代替要刪除的結點數據並遞歸刪除該結點(此時爲null),因爲
右子樹的最小結點不可能有左孩子,所以第二次刪除較爲容易。
z的左子樹和右子樹均不空。找到z的後繼y,因爲y一定沒有左子樹,所以可以刪除y,
並讓y的父親節點成爲y的右子樹的父親節點,並用y的值代替z的值.如圖:
刪除操作源碼:
-
-
public void remove(T t)
-
{
-
rootTree = remove(t,rootTree);
-
}
-
public BinaryNode<T> remove(T t,BinaryNode<T> node)
-
{
-
if(node == null)
-
return node;
-
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;
-
-
}
完整源碼
-
<p></p><pre name="code" class="java">package com.kiritor;
-
-
-
-
-
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
-
;
-
return node;
-
}
-
-
public BinaryNode<T> remove(T t,BinaryNode<T> node)
-
{
-
if(node == null)
-
return node;
-
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>
-