递归的二叉查找树Java实现
package practice;
public class TestMain {
    public static void main(String[] args) {
        int[] ao = {50,18,97,63,56,3,71,85,54,34,9,62,45,94,66,65,7,19,22,86};
        Integer[] a = new Integer[20];
        for (int i = 0; i < a.length; i++) {
            a[i] = new Integer(ao[i]);
        }
        BinarySortTree<Integer, String> tree = new BinarySortTree<Integer, String>();
        for (int i = 0; i < a.length; i++) {
            tree.put(a[i], a[i].toString());
        }
        /*tree.delete(3);
        System.out.println("min = "+tree.min()+" max = "+tree.max());
        tree.delete(97);
        System.out.println("min = "+tree.min()+" max = "+tree.max());
        tree.delete(19);
        tree.delete(18);
        tree.delete(85);
        System.out.println();
        tree.delete(99);*/
    }
}
/*
 * 二叉查找树及其操作的递归实现
 * 二叉查找树:左节点比根节点小,左节点比根节点大。
 */
class BinarySortTree<K extends Comparable<K>, V>{
    Node root;
    /*
     * Node结点类
     */
    class Node{
        private Node left, right; //左右子树
        private K key;
        private V value;
        private int N; //节点所在树的子节点数(包括自己)
        private Node(K key, V value) {
            this.key = key;
            this.value = value;
            this.N = 1;
        }        
        public K getKey() {
            return key;
        }
    }
    /*
     * 插入新节点
     * O(lgn)
     */
    public void put(K key, V value) {
        root = put(key, value, root);
    }
    private Node put(K key, V value, Node node) {
        if (node == null) { return new Node(key, value);}
        if (compare(key, node.key) == 0)     { node.value = value;} //如果key相等则更新值
        else if (compare(key, node.key) < 0) { node.left = put(key, value, node.left);} //进入左子树
        else if (compare(key, node.key) > 0) { node.right = put(key, value, node.right);} //进入右子树
        node.N = size(node.left) + size(node.right) + 1; //子节点数
        return node;
    }
    /*
     * 查找
     */
    public V get(K key) {
        return get(key, root);
    }
    private V get(K key, Node node) {
        if (node == null) { return null;}
        if (compare(key, node.key) < 0)      { return get(key, node.left);}
        else if (compare(key, node.key) > 0) { return get(key, node.right);}
        else                                 { return node.value;} //递归结束条件,找到key
    }
    /*
     * 获取最大最小值
     */
    public K min() {
        return min(root).key;
    }
    private Node min(Node node) {
        if (node.left == null) { return node;}
        else                   { return min(node.left);}
    }
    public K max() {
        return max(root).key;
    }
    private Node max(Node node) {
        if (node.right == null) { return node;}
        else                    { return max(node.right);}
    }
    /*
     * 获取键的排名
     */
    public int rank(K key) {
        return rank(key, root);
    }
    private int rank(K key, Node node) {
        if (node == null) { return 0;} //键不存在返回0
        if (compare(key, node.key) < 0)      { return rank(key, node.left);}
        else if (compare(key, node.key) > 0) { return size(node.left) + 1 + rank(key, node.right);}
                                             //当查找进入右子树时,加上同级左子树的大小,再加1(父节点本身)
        else                                 { return size(node.left);} //该节点左子树的大小(它的左子树的key全部比它小)
    }
    /*
     * 根据排名获取键
     */
    public Node select(int N) {
        return select(N, root);
    }
    private Node select(int N, Node node) {
        int t = size(node.left) + 1; //获取当前节点在以它为根节点的树中的排名(从1开始排)
        if (N < t)      { return select(N, node.left);} //与当前排名比较,选择进入左子树还是右子树
        else if (N > t) { return select(N - t, node.right);}
        //进入右子树时,右子树所有的节点的排名都要加上"同级左子树的大小,再加1(父节点本身)",所以 N - t
        else            { return node;}
    }
    /*
     * 删除最小键
     */
    public void deleteMin() {
        root = deleteMin(root);
    }
    private Node deleteMin(Node node) {
        if (node.left == null) { return node.right;} //将最小节点的右子树连在他的父节点上即将它删除
        node.left = deleteMin(node.left);
        node.N = size(node.left) + size(node.right) + 1; //更新树的大小
        return node;
    }
    /*
     * 删除指定键
     */
    public void delete(K key) {
        root = delete(key, root);
    }
    private Node delete(K key, Node node) {
        if (node == null) { return null;} //找不到键,不做任何处理,原样返回
        if (compare(key, node.key) < 0)      { node.left = delete(key, node.left);} //向左向右找
        else if (compare(key, node.key) > 0) { node.right = delete(key, node.right);}
        else {
            if (node.right == null) { return node.left;} //如果要删的节点有一边时null,直接把另一条子树连到父节点上
            if (node.left== null)   { return node.right;}
            /*Node tnode = min(node.right);
            node.right = deleteMin(node.right);
            tnode.left = node.left;
            tnode.right = node.right;
            tnode.N = size(tnode.left) + size(tnode.right) + 1;
            return tnode;*/
            //上下两段代码实现了同样的功能,充分体现了差距
            Node tnode = node;  //将右子树中的最小值(后继节点)连到父节点上,或左子树中的最大值(前趋节点)也可以
            node = min(tnode.right);
            node.right = deleteMin(tnode.right); //把将要连到父节点上的那个后继节点在当前位置删除
            node.left = tnode.left; //更新左右子树
        }
        node.N = size(node.left) + size(node.right) + 1; //更新树的大小
        return node;
    }
    /*
     * key1 <  key2 -1
     * key1 >  key2  1
     * key1 == key2  0
     */
    private int compare(K key1, K key2) {
        return key1.compareTo(key2);
    }
    private int size(Node node) {
        if (node == null) { return 0;}
        else              { return node.N;}
    }
    /*
     * 中序遍历
     */
    public void print(Node node) {
        if (node == null) {
            return;
        }
        print(node.left);
        System.out.print(node.key+" ");
        print(node.right);
    }
}
算法动态演示
http://www.cs.usfca.edu/~galles/visualization/BST.html
递归的二叉查找树Java实现的更多相关文章
- 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
		前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ... 
- 二叉树3种递归和非递归遍历(Java)
		import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ... 
- 算法——快速排序迭代式和递归式的Java实现
		快速排序迭代式和递归式的Java实现 快速排序基于分治法的思想,在待排序表中任选一值作为中枢值 pivot,一趟快排将所有大于该值的元素置于一边,小于该值的元素置于另一边,这样一个元素在排序中的最终位 ... 
- 数据结构实现(四)二叉查找树java实现
		转载 http://www.cnblogs.com/CherishFX/p/4625382.html 二叉查找树的定义: 二叉查找树或者是一颗空树,或者是一颗具有以下特性的非空二叉树: 1. 若左子树 ... 
- 化繁为简 经典的汉诺塔递归问题 in Java
		问题描述 在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑 ... 
- 递归-归并排序  思想 JAVA实现
		已知一个数组 15.58.61.75.21.32.89.4.78.83.采用递归实现的归并排序将数组有序. 分治策略:(摘自<算法导论>) 在分治策略中,我们采用递归解决问题 分解:将 ... 
- 二叉查找树--java
		package com.test.tree; public class BinarySearchTree<T extends Comparable<? super T>> { ... 
- 非递归遍历二叉树Java版的实现代码(没写层次遍历)
		直接上代码呵呵,里面有注解 package www.com.leetcode.specificProblem; import java.util.ArrayList; import java.util ... 
- 二叉树的递归插入【Java实现】
		C++中由于有指针的存在,可以让二叉树节点指针的指针作为插入函数的实参,在函数体内通过*操作实现对真实节点指针.节点左孩子指针.节点右孩子指针的改变,这样很容易使用递归将大树问题转化到小树问题.但在J ... 
随机推荐
- ExtJs的expand和collapse
			最近在研究ExtJs的窗口组件(Ext.window),关于扩展显示expand和折叠显示collapse的一点心得记录一下,以便后查. var win2 = new Ext.window({ id ... 
- [js高手之路]es6系列教程 - 解构详解
			解构通俗点说,就是通过一种特定格式,快捷的读取对象/数组中的数据的方法, es6之前,我们通过对象名称[键] 读取数据 var User = { 'name' : 'ghostwu', 'age' : ... 
- python实战第一天-pymysql模块并练习
			操作系统 Ubuntu 15.10 IDE & editor JetBrains PyCharm 5.0.2 ipython3 Python版本 python-3.4.3 安装pymysql模 ... 
- ZooKeeper笔记——技术点汇总
			目录 · ZooKeeper安装 · 分布式一致性理论 · 一致性级别 · 集中式系统 · 分布式系统 · ACID特性 · CAP理论 · BASE理论 · 一致性协议 · ZooKeeper概况 ... 
- vue指令v-else-if示例解析
			表示 v-if 的 "else if 块".可以链式调用. <div id="app"> <p v-if="isRender&quo ... 
- 白话ASP.NET MVC之二:Controller激活系统的概览
			前文简介:我们抽象类路由规则的对象,RouteBase是路由对象的抽象基类,ASP.NET 的路由系统中有唯一一个从RouteBase继承的路由对象,那就是Route类型了.我们注册了路由对象Rout ... 
- 再起航,我的学习笔记之JavaScript设计模式06(工厂方法模式)
			上一次已经给大家介绍了简单工厂模式,相信大家对创建型设计模式有了初步的了解,本次我将给大家介绍的是工厂方法模式. 工厂方法模式 工厂方法模式(Factory Method):通过对产品类的抽象使其创建 ... 
- 利用GeoIP数据库及API进行地理定位查询 Java
			地理定位查询的的数据库比较多,而且大多都开放一些free的版本 国内的有纯真数据库等,但是他只提供文本的地理位置信息,不提供经纬度数据 当应用到google map时,就不可以了 国外的有MaxMin ... 
- Linux操作系统-命令-vmstat
			叨叨两句 涉及监控服务器性能的命令,除了有vmstat之外,还有top.iostat.netstat.本文只是介绍一下这4个命令中的1个.剩下的3个命令可以参考以下网上的资料就差不多能会了. 推荐to ... 
- SpringMVC实现垂直搜索引擎
			本篇博客是在上一篇<Lucene搜索引擎+HDFS+MR完成垂直搜索>的基础上,在数据收集之后的JSP/Servlet方面,换为SpringMVC框架来实现. 借助SpringMVC技术完 ... 
