Data Structure - Binary Search Tree (Java)

版权声明:欢迎转载并请注明出处,谢谢~~ https://blog.csdn.net/chimomo/article/details/85249234
package chimomo.learning.java.datastructure;

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

    /**
     * The tree root.
     */
    private BinaryNode<T> root;

    /**
     * Construct the tree.
     */
    public BinarySearchTree() {
        root = null;
    }

    // Test program
    public static void main(String[] args) throws Exception {
        // Create binary search tree.
        BinarySearchTree<Integer> t = new BinarySearchTree<>();
        final int NUMS = 4000;
        final int GAP = 37;

        // Insert.
        for (int i = GAP; i != 0; i = (i + GAP) % NUMS) {
            t.insert(i);
        }

        // Get height.
        System.out.println("Height: " + t.height(t.root));

        // Remove.
        for (int i = 1; i < NUMS; i += 2) {
            t.remove(i);
        }

        System.out.println("Checking... (no more output means success)");

        // Print tree.
        if (NUMS < 40) {
            t.printTree();
        }

        // Find min and find max.
        if (t.findMin() != 2 || t.findMax() != NUMS - 2) {
            System.out.println("FindMin or FindMax error!");
        }

        // Contains.
        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!");
            }
        }
    }

    /**
     * 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 The smallest item or null if empty.
     */
    public T findMin() throws Exception {
        if (isEmpty()) {
            throw new Exception("Binary search tree is empty!");
        }
        return findMin(root).element;
    }

    /**
     * Find the largest item in the tree.
     *
     * @return The largest item of null if empty.
     */
    public T findMax() throws Exception {
        if (isEmpty()) {
            throw new Exception("Binary search tree is empty!");
        }
        return findMax(root).element;
    }

    /**
     * Find an item in the tree.
     *
     * @param x The item to search for.
     * @return True if found, false otherwise.
     */
    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 binary search 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);
        } else {
            // Duplicate; do nothing.
        }

        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) {
        // Item not found; do nothing.
        if (t == null) {
            return null;
        }

        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 The 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 The 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 The item to search for.
     * @param t The node that roots the subtree.
     * @return True if contains, false otherwise.
     */
    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 <AnyType> Any type
     */
    private static class BinaryNode<AnyType> {
        AnyType element;            // The data in the node
        BinaryNode<AnyType> left;   // Left child
        BinaryNode<AnyType> right;  // Right child

        // Constructors
        BinaryNode(AnyType theElement) {
            this(theElement, null, null);
        }

        BinaryNode(AnyType theElement, BinaryNode<AnyType> left, BinaryNode<AnyType> right) {
            element = theElement;
            this.left = left;
            this.right = right;
        }
    }

}

/*
Output:
Height: 119
Checking... (no more output means success)
*/

猜你喜欢

转载自blog.csdn.net/chimomo/article/details/85249234