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;
}
}
}