现在的位置: 首页 > 综合 > 正文

19 二叉查找树 (一)

2013年01月10日 ⁄ 综合 ⁄ 共 3597字 ⁄ 字号 评论关闭
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;
		}
		
	}
}

抱歉!评论已关闭.