二叉搜索树V2.0(含比较器,Java语言描述)

更新说明

二叉搜索树V1.0的编程实现中,我们实现了BST的查找、插入,左右儿子删除的功能,但写的确实很一般,这里就Update一下。

功能介绍

  • void insert(x) → Insert x
  • void remove(x) → Remove x
  • boolean contains(x) → Return true if x is present
  • Comparable findMin() → Return smallest item
  • Comparable findMax() → Return largest item
  • boolean isEmpty() → Return true if empty; else false
  • void makeEmpty() → Remove all items
  • void printTree() → Print tree in sorted order

异常类

当集合容器为空的时候就不能够删除或获取元素,这时就会出现一种异常,命名为UnderflowException:

/**
 * Exception class for access in empty containers
 * such as stacks, queues, and priority queues.
 */
public class UnderflowException extends RuntimeException {}

编程实现

/**
 * Implements an unbalanced binary search tree.
 * Note that all "matching" is based on the compareTo method.
 */
public class BinarySearchTree<T extends Comparable<? super T>> {

    /**
     *  The tree root.
     */
    private BinaryNode<T> root;
    
    /**
     * Construct the tree.
     */
    public BinarySearchTree() {
        root = null;
    }

    /**
     * Insert into the tree; duplicates are ignored.
     * @param x the item to insert.
     */
    public void insert(T x) {
        root = insert(x, root);
    }

    /**
     * Remove from the tree. Nothing is done if x is not found.
     * @param x the item to remove.
     */
    public void remove(T x) {
        root = remove(x, root);
    }

    /**
     * Find the smallest item in the tree.
     * @return smallest item or null if empty.
     */
    public T findMin() {
        if(isEmpty()) {
            throw new UnderflowException( );
        }
        return findMin(root).element;
    }

    /**
     * Find the largest item in the tree.
     * @return the largest item of null if empty.
     */
    public T findMax( )
    {
        if( isEmpty( ) )
            throw new UnderflowException( );
        return findMax( root ).element;
    }

    /**
     * Find an item in the tree.
     * @param x the item to search for.
     * @return true if not found.
     */
    public boolean contains(T x) {
        return contains(x, root);
    }

    /**
     * Make the tree logically empty.
     */
    public void makeEmpty() {
        root = null;
    }

    /**
     * Test if the tree is logically empty.
     * @return true if empty, false otherwise.
     */
    public boolean isEmpty() {
        return root == null;
    }

    /**
     * Print the tree contents in sorted order.
     */
    public void printTree() {
        if(isEmpty()) {
            System.out.println("Empty tree");
        } else {
            printTree(root);
        }
    }

    /**
     * Internal method to insert into a subtree.
     * @param x the item to insert.
     * @param t the node that roots the subtree.
     * @return the new root of the subtree.
     */
    private BinaryNode<T> insert(T x, BinaryNode<T> t) {
        if(t == null) {
            return new BinaryNode<>( 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);
        }
        return t;
    }

    /**
     * Internal method to remove from a subtree.
     * @param x the item to remove.
     * @param t the node that roots the subtree.
     * @return the new root of the subtree.
     */
    private BinaryNode<T> remove(T x, BinaryNode<T> t) {
        if(t == null) {
            return null;   // Item not found; do nothing
        }
        int 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 children
            t.element = findMin(t.right).element;
            t.right = remove(t.element, t.right);
        } else {
            t = (t.left != null) ? t.left : t.right;
        }
        return t;
    }

    /**
     * Internal method to find the smallest item in a subtree.
     * @param t the node that roots the subtree.
     * @return node containing the smallest item.
     */
    private BinaryNode<T> findMin(BinaryNode<T> t) {
        if(t == null) {
            return null;
        } else if(t.left == null) {
            return t;
        }
        return findMin(t.left);
    }

    /**
     * Internal method to find the largest item in a subtree.
     * @param t the node that roots the subtree.
     * @return node containing the largest item.
     */
    private BinaryNode<T> findMax(BinaryNode<T> t) {
        if(t != null) {
            while(t.right != null) {
                t = t.right;
            }
        }
        return t;
    }

    /**
     * Internal method to find an item in a subtree.
     * @param x is item to search for.
     * @param t the node that roots the subtree.
     * @return node containing the matched item.
     */
    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;    // Match
        }
    }

    /**
     * Internal method to print a subtree in sorted order.
     * @param t the node that roots the subtree.
     */
    private void printTree(BinaryNode<T> t) {
        if(t != null) {
            printTree(t.left);
            System.out.println(t.element);
            printTree(t.right);
        }
    }

    /**
     * Internal method to compute height of a subtree.
     * @param t the node that roots the subtree.
     */
    private int height(BinaryNode<T> t) {
        if(t == null) {
            return -1;
        } else {
            return 1 + Math.max(height(t.left), height(t.right));
        }
    }

    /**
     * Basic node stored in unbalanced binary search trees.
     * @param <T>
     */
    private static class BinaryNode<T> {
        BinaryNode( T theElement ) {
            this(theElement, null, null);
        }

        BinaryNode(T theElement, BinaryNode<T> lt, BinaryNode<T> rt) {
            element  = theElement;
            left     = lt;
            right    = rt;
        }

        T element;            // The data in the node
        BinaryNode<T> left;   // Left child
        BinaryNode<T> right;  // Right child
    }

}

测试

public class BinarySearchTreeTest {
    public static void main(String [] args) {
        BinarySearchTree<Integer> t = new BinarySearchTree<>();
        final int NUMS = 4000;
        final int GAP  =   37;
        System.out.println("Checking... (no more output means success)");
        for(int i = GAP; i != 0; i = (i + GAP) % NUMS) {
            t.insert(i);
        }
        for(int i = 1; i < NUMS; i+= 2) {
            t.remove(i);
        }
        if(NUMS < 40) {
            t.printTree();
        }
        if(t.findMin() != 2 || t.findMax( ) != NUMS-2) {
            System.out.println("FindMin or FindMax error!");
        }
        for(int i = 2; i < NUMS; i+=2) {
            if(!t.contains(i)) {
                System.out.println("Find error1!");
            }
        }
        for(int i = 1; i < NUMS; i+=2) {
            if(t.contains(i)) {
                System.out.println("Find error2!");
            }
        }
    }
}

测试结果:

Checking... (no more output means success)
发布了570 篇原创文章 · 获赞 1179 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/weixin_43896318/article/details/104456288
今日推荐