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; } } }
相关文章推荐
- 【算法Everyday】第一日 二叉查找树转双向链表
- LeetCoder 19. Remove Nth Node From End of List
- 19.图的存储表示----邻接矩阵表示法
- H5 19
- 二叉查找树
- 剑指offer 19---二叉树的镜像
- 二叉查找树
- 19 在Linux下运行C语言程序
- 让你提前认识软件开发(19):C语言中的协议及单元测试示例
- 删除二叉查找树的节点
- 19 个 Android 开发工具
- jquery19 ajax()
- 我的java学习日记(19)
- 【Java学习笔记】19:Guarded Suspension Pattern
- 《裸辞的程序猿漂流记》19
- 19 《黑石头的爱与恨:煤的故事》 -豆瓣评分7.4
- 从程序员到项目经理(19):想改变任何人都是徒劳的【转载】
- 19 闭包函数、简单装饰器
- 二叉查找树
- Unity Learning for Day 19