二叉查找树
来源:互联网 发布:手机淘宝首页代码 编辑:程序博客网 时间:2024/04/30 15:08
使二叉树成为二叉查找树的性质是,对于树中的每个节点 X ,它的左子树中所有项的值小于 X 中的值,而它右子树中所有项的值大于 X 中的值。
注意,这意味着该树所有的元素可以用某种一致的方式排序。
首先定义一个节点类:
private static class BinaryNode<T>{T element;BinaryNode<T> left;BinaryNode<T> right;public BinaryNode( T element ) {this( element, null, null );}public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {this.element = element;this.left = left;this.right = right;}}
public boolean contains( T x ){return contains( x, root );}private boolean contains( T x, BinaryNode<T> t ){if( t == null )return false;int compareResult = x.compareTo( t.element );if( compareResult < 0 ){return contains( x, t.left );}else if( compareResult > 0 ){return contains( x, t.right );}else{return true;}}
递归方法实现:
public T findMin(){if( isEmpty() )throw new UnderflowException();return findMin( root ).element;}/** * 递归的方法 * @param t * @return * * Date :2012-7-6 * Author :GongQiang */private BinaryNode<T> findMin( BinaryNode<T> t ){if( t == null ){return null;}else if( t.left == null ){return t;}return findMin( t.left );}非递归方法实现:
public T findMax(){if( isEmpty() )throw new UnderflowException();return findMax( root ).element;}/** * 循环迭代 * @param t * @return * * Date :2012-7-6 * Author :GongQiang */private BinaryNode<T> findMax( BinaryNode<T> t ){if( t!= null ){while( t.right != null )t = t.right;}return t;}
insert 方法
为了将 X 插入到数 T 中,你可以像用 contains 那样沿着树查找。如果找到 X ,则什么也不用做(或做一些“更新”)。否则将 X 插入到遍历的路径上的最后一点上。
public void insert( T x ){root = insert( x, root );}private BinaryNode<T> insert( T x, BinaryNode<T> t ){if( t == null )return new BinaryNode<T>( x, null, null );int compareResult = x.compareTo( t.element );if( compareResult < 0 ){t.left = insert( x, t.left );}else if( compareResult > 0 ){t.right = insert( x, t.right );}else{; // 重复,不做任何操作}return t;}
如果节点是一片树叶,那么它可以被立即删除;
如果节点有一个儿子,则该节点可以在其父节点调整自己的链绕过该节点后被删除;
如果处理具有两个儿子的节点。一般的删除策略是用其右子树的最小的数据代替该节点的数据并递归地删除那个节点(现在它是空的)。因为右子树中的最小的节点不可能有左儿子,所以第二次 remove 要容易。
public void remove( T x ){root = remove( x, root );}private BinaryNode<T> remove( T x, BinaryNode<T> t ){if( t == null )return t; // Item not found; do nothingint compareResult = x.compareTo( t.element );if( compareResult < 0 ){t.left = remove( x, t.left );}else if( compareResult > 0 ){t.right = remove( x, t.right );}else if( t.left != null && t.right != null ){ // Two childrent.element = findMin( t.right ).element;t.right = remove( t.element, t.right );}else{t = ( t.left != null )? t.left : t.right;}return t;}
如果删除的次数不多,通常使用的策略是懒惰删除:当一个元素要被删除时,它仍留在树中,而只是被标记为删除。这特别是在有重复项时很常用,因为此时记录出现频率数的域可以减 1 。如果树中的实际节点数和“被删除”的节点数相同,那么树的深度预计只是上升一个小的常数,因此,存在一个与懒惰删除相关的非常小的时间损耗。再有,如果被删除的项重新插入的,那么分配一个新单元的开销就避免了。
完整代码:
public class BinarySearchTree<T extends Comparable<? super T>> {private static class BinaryNode<T>{T element;BinaryNode<T> left;BinaryNode<T> right;public BinaryNode( T element ) {this( element, null, null );}public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {this.element = element;this.left = left;this.right = right;}}private BinaryNode<T> root;public BinarySearchTree() {root = null;}public void makeEmpty(){root = null;}public boolean isEmpty(){return root == null;}public boolean contains( T x ){return contains( x, root );}private boolean contains( T x, BinaryNode<T> t ){if( t == null )return false;int compareResult = x.compareTo( t.element );if( compareResult < 0 ){return contains( x, t.left );}else if( compareResult > 0 ){return contains( x, t.right );}else{return true;}}public T findMin(){if( isEmpty() )throw new UnderflowException();return findMin( root ).element;}/** * 递归的方法 * @param t * @return * * Date :2012-7-6 * Author :GongQiang */private BinaryNode<T> findMin( BinaryNode<T> t ){if( t == null ){return null;}else if( t.left == null ){return t;}return findMin( t.left );}public T findMax(){if( isEmpty() )throw new UnderflowException();return findMax( root ).element;}/** * 循环迭代 * @param t * @return * * Date :2012-7-6 * Author :GongQiang */private BinaryNode<T> findMax( BinaryNode<T> t ){if( t!= null ){while( t.right != null )t = t.right;}return t;}public void insert( T x ){root = insert( x, root );}private BinaryNode<T> insert( T x, BinaryNode<T> t ){if( t == null )return new BinaryNode<T>( x, null, null );int compareResult = x.compareTo( t.element );if( compareResult < 0 ){t.left = insert( x, t.left );}else if( compareResult > 0 ){t.right = insert( x, t.right );}else{; // 重复,不做任何操作}return t;}public void remove( T x ){root = remove( x, root );}private BinaryNode<T> remove( T x, BinaryNode<T> t ){if( t == null )return t; // Item not found; do nothingint compareResult = x.compareTo( t.element );if( compareResult < 0 ){t.left = remove( x, t.left );}else if( compareResult > 0 ){t.right = remove( x, t.right );}else if( t.left != null && t.right != null ){ // Two childrent.element = findMin( t.right ).element;t.right = remove( t.element, t.right );}else{t = ( t.left != null )? t.left : t.right;}return t;}public void printTree(){//前序输出printTree( root );}private void printTree( BinaryNode<T> t ){if( t != null ){printTree( t.left );System.out.println( t.element );printTree( t.right );}}}class UnderflowException extends RuntimeException{private static final long serialVersionUID = 1L;}
- 查找--二叉查找树
- 二叉树、二叉查找树
- 二叉树 & 二叉查找树
- 【查找结构】二叉查找树
- 查找之二叉树查找
- 查找之二叉树查找
- 查找:二叉查找树总结
- 二叉树查找树...
- 二叉树查找树
- 查找--遍历二叉树
- 二叉查找树
- 二叉查找树实现
- 二叉查找树
- 动态二叉查找树
- 最优二叉查找树
- 二叉查找树
- 二叉查找树
- 平衡二叉查找树
- V4L2 简介
- C#编程好习惯
- JAVA学习网站推荐
- android Fragments详解七:fragement示例
- Spring之AOP:我行之我见
- 二叉查找树
- 将任意格式转换为JSON数据格式的工具类
- 创业公司如何应对大公司的冲击
- sam9260目标板上设定thttpd服务后出现/usr/sbin/thttpd: unknown user - 'httpd'错误提示
- 知名网站的技术实现
- 处理XX医院服务器定时死机过程 TNS-12547 TNS:lost contact
- ie6下图片透明变灰色的解决方案
- 导出Excel或word文档
- Lisp项目构建和包管理工具