您的位置:首页 > 其它

19 二叉查找树 (一)

2012-11-28 18:03 148 查看
package nuaa.ds;

//对于重复项:只记录一项,维护对重复项的计数
public class BinarySearchTree<T extends Comparable<? super T>> {

protected BinaryNode<T> root;

public BinarySearchTree(){
}

public void insert(T x) throws Exception{
root = this.insert(x, root);
}

//递归插入
protected BinaryNode<T> insert(T x,BinaryNode<T> t) throws Exception{
if(t==null)//没有更深的节点,同时包含了树本身为空的情况
t = new BinaryNode<T>(x);
else if(x.compareTo(t.element)<0)       //把生成的的左(右)节点
t.left = this.insert(x, t.left);    //或者原始的左(右)节点
else if(x.compareTo(t.element)>0)		//值返回给树的上一层,一
t.right = this.insert(x, t.right);  //直到最上层返回根
else
throw new Exception("DuplicateItem:"+x);
return t;
}

public void remove(T x) throws Exception{
root = remove(x,root);
}

//很多无意义的赋值
protected BinaryNode<T> remove(T x,BinaryNode<T> t) throws Exception{
if(t==null)
throw new Exception("Item Not Found");
if(x.compareTo(t.element)<0)
t.left = remove(x,t.left);
else if(x.compareTo(t.element)>0)
t.right = remove(x,t.right);
else if(t.left!=null&&t.right!=null){
t.element = findMin(t.right).element;//替换右子树的最小元素
t.right = removeMin(t.right);//删除右子树中的最小节点
}else{
t = (t.left!=null)?t.left:t.right;
}
return t;
}

public void removeMin() throws Exception{
root = this.removeMin(root);
}

protected BinaryNode<T> removeMin(BinaryNode<T> t) throws Exception{
if(t==null)
throw new Exception("Item Not Found:"+t);
else if(t.left!=null){                 //有左子树进入左子树
t.left = this.removeMin(t.left);   //
return t;						   //本层有左子树的就返回本层的根给上层
}else
return t.right;  //没有就返回右子树给上层
}

private T elementAt(BinaryNode<T> t){
return t==null?null:t.element;
}

public T findMin(){
return this.elementAt(this.findMin(root));
}
protected BinaryNode<T> findMin(BinaryNode<T> t){
if(t!=null)
while(t.left!=null)
t = t.left;
return t;
}

public T findMax(){
return this.elementAt(this.findMax(root));
}
private BinaryNode<T> findMax(BinaryNode<T> t){
if(t!=null)
while(t.right!=null)
t = t.right;
return t;
}

public T find(T x){
return this.elementAt(this.find(x, root));
}

private BinaryNode<T> find(T x,BinaryNode<T> t){
while(t!=null){
if(x.compareTo(t.element)<0)
t = t.left;
else if(x.compareTo(t.element)>0)
t = t.right;
else
return t;
}
return null;//NOT_FOUND
}

public void makeEmpty(){
this.root = null;
}
public boolean isEmpty(){
return root==null;
}

}


二叉查找树在每个节点处多加一个字段,存放下面的子孙个数,就能很容易的找到第k个节点:左子树的个数+1是否等于k,等于就返回,小于就进入右子树,大于就进入左子树,递归继续往下执行。最后找不到了就返回错误

package nuaa.ds;

import java.util.NoSuchElementException;

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

public T findKth(int k){
return findKth(k,root).element;
}

protected BinaryNode<T> findKth(int k,BinaryNode<T> t){
if(t==null)
throw new IllegalArgumentException();
int leftSize = t.left!=null ?
((BinaryNodeWithSize<T>)t.left).size : 0;
if(k<=leftSize)
return findKth(k,t.left);
if(k==leftSize+1)
return t;
return findKth(k-leftSize-1,t.right);
}

protected BinaryNode<T> insert(T x,BinaryNode<T> tt) throws Exception{
BinaryNodeWithSize<T> t = (BinaryNodeWithSize<T>)tt;
if(t==null)
t = new BinaryNodeWithSize<T>(x);
else if(x.compareTo(t.element)>0)
t.right = insert(x,t.right);
else if(x.compareTo(t.element)<0)
t.left = insert(x,t.left);
else
throw new Exception("Duplicate item");
t.size++;
return t;
}

protected BinaryNode<T> remove(T x,BinaryNode<T> tt) throws Exception{
if(tt==null)
throw new Exception("empty tree");
if(x.compareTo(tt.element)>0)
tt.right = remove(x,tt.right);
if(x.compareTo(tt.element)<0)
tt.left = remove(x,tt.left);
else if(tt.left!=null&&tt.right!=null){
tt.element = findMin(tt.right).element;
tt.right = removeMin(tt.right);
}else
return tt.left!=null ? tt.left : tt.right;
((BinaryNodeWithSize<T>)tt).size--;
return tt;
}

protected BinaryNode<T> removeMin(BinaryNode<T> tt){
if(tt==null)
throw new NoSuchElementException();
if(tt.left==null)
return tt.right;
tt.left = removeMin(tt.left);
((BinaryNodeWithSize<T>)tt).size--;
return tt;
}

private static class BinaryNodeWithSize<T> extends BinaryNode<T>{
int size;
BinaryNodeWithSize(T x){
super(x);
size = 0;
}

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