二叉搜索树 BinarySearchTree

来源:互联网 发布:西蒙和加芬克尔 知乎 编辑:程序博客网 时间:2024/05/29 10:46

动态查找如何组织数据? 二分查找(Binary Search)的效率非常高,时间复杂度为O(logN) ,但是所有元素必须是有序的,所以可以把数据放进树中,以二叉搜索树的方式来组织数据。

BinarySearchTree.java

/*** @describe * @version 2016年4月16日* @author dotdoppler@yeah.net*/package doppler.tree;import doppler.Underflow;public class BinarySearchTree<T extends Comparable<? super T>> {    // 根节点    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);    }    public T findMin() throws Exception {        if (isEmpty())            throw new Underflow("Empty tree !");        return findMin(root).element;    }    public T findMax() throws Exception{        if(isEmpty())            throw new Underflow("Empty tree !");        return findMax(root).element;    }    public void insert(T x){        root = insert(x,root);    }    public void remove(T x){        root = remove(x,root);    }    public void printTree(){        if(isEmpty())            System.out.println("Empty tree !");        else            printTree(root);    }    // 查找的效率取决于树的高度    private boolean contains(T x, BinaryNode<T> tree) {        // 尾递归        // if(tree == null)        // return false;        // int compareResult = x.compareTo( tree.element );        //        //        // if(compareResult < 0 )        // return contains(x, tree.leftTree);        // else if (compareResult > 0)        // return contains(x, tree.rightTree);        // else        // return true; //match        //        // while循环        while (tree != null) {            int compareResult = x.compareTo(tree.element);            if (compareResult < 0)                tree = tree.leftTree;            else if (compareResult > 0)                tree = tree.rightTree;            else                return true; // match        }        return false;    }    // 这里同样可以使用尾递归或者while循环    private BinaryNode<T> findMin(BinaryNode<T> tree) {        // //尾递归        // if(tree == null)        // return null;        // else if(tree.leftTree == null)        // return tree;        // return findMin(tree.leftTree);        // while循环        if (tree == null)            return null;        while (tree.leftTree != null)             tree = tree.leftTree;        return tree; // found    }    private BinaryNode<T> findMax(BinaryNode<T> tree) {        if (tree == null)            return null;        while(tree.rightTree != null)            tree = tree.rightTree;        return tree;    }    //插入(尾递归)    private BinaryNode<T> insert(T x,BinaryNode<T> tree){        if(tree == null)            return new BinaryNode<T>(x, null, null);        int compareResult = x.compareTo(tree.element);        if(compareResult < 0)            tree.leftTree=insert(x, tree.leftTree);        else if(compareResult > 0)            tree.rightTree=insert(x, tree.rightTree);        else             ;//重复元素        return tree;    }    /*     * 思路是:先是递归地找到要删除的元素,     * 找到该元素后,分两种情况,一是被删除结点有两个自子结点,策略是在右子树中找到最小的元素填充被删除的元素,     * 二是,被删除元素没有子结点(被删除元素为叶结点)或者只有一个子结点,则被删除的元素的父结点指向的被删除元素的子结点。     */    private BinaryNode<T> remove(T x,BinaryNode<T> tree){        if( tree == null)            return tree;        int compareResult = x.compareTo(tree.element);        if(compareResult < 0)//左子树递归删除            tree.leftTree = remove(x, tree.leftTree);        else if(compareResult > 0)//右子树递归删除            tree.rightTree = remove(x, tree.rightTree);        //match,找到该元素        else if (tree.leftTree != null && tree.rightTree != null)//待删除节点有两颗子树        {            tree.element = findMin(tree.rightTree).element;            tree.rightTree = remove(tree.element, tree.rightTree);        }        else             tree = (tree.leftTree != null) ? tree.leftTree : tree.rightTree;        return tree;    }    private void printTree(BinaryNode<T> tree){        if(tree != null)        {            printTree(tree.leftTree);            System.out.print("  "+tree.element);            printTree(tree.rightTree);        }    }    // 嵌套的BinaryNode类    private static class BinaryNode<T> {        private T element;        private BinaryNode<T> leftTree;        private BinaryNode<T> rightTree;        @SuppressWarnings("unused")        BinaryNode(T theElement) {            this(theElement, null, null);        }        BinaryNode(T theElement, BinaryNode<T> lt, BinaryNode<T> rt) {            element = theElement;            leftTree = lt;            rightTree = rt;        }    }}

BinarySearchTreeDemo.java

/*** @describe* @version 2016年4月16日* @author dotdoppler@yeah.net*/package doppler.test;import doppler.tree.BinarySearchTree;public class BinarySearchTreeDemo {    public static void main(String[] args)throws Exception {        BinarySearchTree<Integer> bst = new BinarySearchTree<Integer>();        bst.insert(6);        bst.insert(2);        bst.insert(1);        bst.insert(5);        bst.insert(3);        bst.insert(4);        bst.insert(8);        bst.insert(7);        bst.printTree();        System.out.println();        System.out.println("max= " + bst.findMax());        System.out.println("min= " + bst.findMin());        bst.insert(0);        bst.insert(10);        bst.printTree();        System.out.println();        System.out.println("max= " + bst.findMax());        System.out.println("min= " + bst.findMin());        bst.remove(5);        bst.printTree();        System.out.println();        System.out.println("contains 7? " + bst.contains(7)+"  contains 11? " + bst.contains(11));    }}

这里写图片描述

0 0
原创粉丝点击