二分搜索树--完整版

来源:互联网 发布:矩阵的范数 编辑:程序博客网 时间:2024/06/05 06:47

1介绍

包含二分搜索树的插入,删除,遍历,等几乎全部功能 ,如果想知道什么是二分搜索树,请查看我的上一篇博客,废话少说,上代码

2 实现–完整版

import java.util.LinkedList;/** * 二分搜索树 *  * @author xld * * @param <Key> * @param <Value> */public class BST<Key extends Comparable<Key>, Value> {    /**     * 树中的节点 设置为内部类     *      * @author xld     *     */    private class Node {        private Key key;        private Value value;        private Node left, right;        public Node(Key key, Value value) {            this.key = key;            this.value = value;            left = right = null;        }        public Node(Node node){            this.key=node.key;            this.value=node.value;            this.left=node.left;            this.right=this.right;        }    }    // 根节点    private Node root;    // 树中的节点个数    private int count;    // 构造函数 默认构造一棵空二分搜索树    public BST() {        root = null;        count = 0;    }    // 返回二分搜索树节点个数    public int size() {        return count;    }    // 判断二分搜索树是否为空    public boolean isEmpty() {        return count == 0;    }    // 向二分搜索树中插入一个新的(key,value)数据对    public void insert(Key key, Value value) {        root = insert(root, key, value);    }    // 查看二分搜索树中是否包含该元素    public boolean contain(Key key, Value value) {        return contain(root, key);    }    // 查看键值为key的元素在二分搜索树中的value    public Value search(Key key) {        return search(root, key);    }    // 二分搜索树的前序遍历    public void preOrder() {        preOrder(root);    }    // 二分搜索树的中序遍历    public void inOrder() {        inOrder(root);    }    // 二分搜索树的后序遍历    public void postOrder() {        postOrder(root);    }    // 二分搜索树的层序遍历    public void levelOrder() {        // 使用LinkedList 作为队列        LinkedList<Node> q = new LinkedList<Node>();        q.add(root);        while (!q.isEmpty()) {            Node node = q.remove();            System.out.println(node.key);            if (node.left != null)                q.add(node.left);            if (node.right != null)                q.add(node.right);        }    }    // 寻找二分搜索树的最小的键值    public Key minimum() {        assert count != 0;        Node minNode = minimum(root);        return minNode.key;    }    //寻找二分搜索树中最大的键值    public Key maximum(){        assert count!=0;        Node maxNode = maximum(root);        return maxNode.key;    }    //从二分搜索树中删除最小值所在的节点     public void removeMin(){        if(root !=null)            root= removeMin(root);    }    //从二分搜索树中删除最大值所在节点     public void removeMax(){        if(root !=null)            root = removeMax(root);    }    public void remove(Key key){        root = remove(root,key);    }    /**     * 寻找key的floor值,递归算法     * 如果不存在key的floor值(key比BST的最小值还小) 返回null     * @param key     * @return     */    public Key floor(Key key){        if(count==0 || key.compareTo(minimum())<0)            return null;        Node floorNode = floor(root,key);        return floorNode.key;    }    public Key ceil(Key key){        if(count==0 || key.compareTo(maximum())>0)            return null;        Node ceilNode =ceil(root,key);        return ceilNode.key;    }    // **************************    // 二分搜索树的辅助函数    // **************************    /**     * 向以node为根的二分搜索树中,插入节点(key,value),使用递归算法 返回插入节点后的二分搜索树的根     *      * @param node     * @param key     * @param value     * @return     */    private Node insert(Node node, Key key, Value value) {        if (node == null) {            count++;            return new Node(key, value);        }        if (key.compareTo(node.key) == 0)            node.value = value;        else if (key.compareTo(node.key) < 0)            node.left = insert(node.left, key, value);        else            node.right = insert(node.right, key, value);        return node;    }    /**     * 查看以node为根的二分搜索树中是否包含键值为key的节点,使用递归算法 若value不存在 则返回false     *      * @param node     * @param key     * @return     */    private boolean contain(Node node, Key key) {        if (node == null)            return false;        if (key.compareTo(node.key) == 0)            return true;        else if (key.compareTo(node.key) < 0)            return contain(node.left, key);        else            return contain(node.right, key);    }    /**     * 查看以node为根的二分搜索树中键值为key的节点的value值,使用递归算法     *      * @param node     * @param key     * @return     */    private Value search(Node node, Key key) {        if (node == null)            return null;        if (key.compareTo(node.key) == 0)            return node.value;        else if (key.compareTo(node.key) < 0)            return search(node.left, key);        else            return search(node.right, key);    }    /**     * 二分搜索树的前序遍历     *      * @param node     */    private void preOrder(Node node) {        if (node != null) {            System.out.println(node.key);            preOrder(node.left);            preOrder(node.right);        }    }    /**     * 二分搜索树的中序遍历     *      * @param node     */    private void inOrder(Node node) {        if (node != null) {            inOrder(node.left);            System.out.println(node.key);            inOrder(node.right);        }    }    /**     * 二分搜索树的后序遍历     *      * @param node     */    private void postOrder(Node node) {        if (node != null) {            postOrder(node.left);            postOrder(node.right);            System.out.println(node.key);        }    }    /**     * 二分搜索树中最小的节点就是最左侧的节点     * @param node     * @return     */    private Node minimum(Node node){        if(node.left==null)            return node;        return minimum(node.left);    }    private Node maximum(Node node){        if(node.right==null)            return node;        return maximum(node.right);    }    /**     * 删除以node为根的二分搜索树的最小值     * @param node     * @return     */    private Node removeMin(Node node){        //如果以node为根的二分搜索树的左子节点为空,则node为当前最小节点         if(node.left==null){            //保存下当前的node节点的node节点            Node rightNode =node.right;            //将当前node 节点的指向right的指针去除            node.right=null;            //二分搜索树中节点减少一个            count--;            //直接将node节点的right返回顶替当前节点            return rightNode;        }        //将返回节点作为当前界定啊的左节点         node.left=removeMin(node.left);        return node;    }    private Node removeMax(Node node){        if(node.right==null){            Node leftNode = node.left;            node.left=null;            count--;            return leftNode;        }        node.right=removeMax(node.right);        return node;    }    /**     * 删除掉以node为根的二分搜索树中键值为key的节点,递归算法     * 返回删除节点后新的二分搜索树的根     * @param node     * @param key     * @return     */    private Node remove(Node node ,Key key){        if(node ==null)            return null;        if(key.compareTo(node.key)<0){            node.left=remove(node.left,key);            return node;        }else if(key.compareTo(node.key)>0){            node.right=remove(node.right,key);            return node;        }else {            //key ==node.key            //待删除节点左子树为空的情况            if(node.left==null){                Node rightNode = node.right;                node.right=null;                count--;                return rightNode;            }            //待删除界定啊右子树为空的情况下             if(node.right==null){                Node leftNode = node.left;                node.left=null;                count--;                return leftNode;            }            //待删除节点左右子树均不为空的情况下             //找到比待删除节点大的最小节点 即待删除右自护中最小节点 用这个界定啊顶替待删除节点的位置            Node successor = new Node (minimum(node.right));            count++;            successor.right= removeMin(node.right);            successor.left=node.left;            node.left = node.right=null;            count--;            return successor;        }    }    /**     * 在以node为根的二叉搜索树中,寻找key的floor值所处的节点,递归算法     * @param node     * @param key     * @return     */    private Node floor(Node node,Key key){        if(node == null)            return null;        //如果node的key值和要寻找的key值相等         //则node 本身就是key的floor节点        if(node.key.compareTo(key)==0)            return node;        //如果node的key值比要寻找的key值大        //则要寻找的key的floor在node的左子树中         if(node.key.compareTo(key)>0)            return floor(node.left,key);        //如果node的key值比要寻找的key小         //则node可能是key的floor节点,也可能不是 需要从node的右子树取寻找一下        Node tempNode = floor(node.right,key);        if(tempNode!=null)            return tempNode;        return node;    }    private Node ceil(Node node,Key key){        if(node == null)            return null;        if(node.key.compareTo(key)==0)            return node;        if(node.key.compareTo(key)<0)            return ceil(node.right,key);        Node tempNode =ceil(node.left,key);        if(tempNode!=null)            return tempNode;        return node;    }}
原创粉丝点击