美文网首页
实现一个二分搜索树

实现一个二分搜索树

作者: xin激流勇进 | 来源:发表于2019-04-10 18:16 被阅读0次
    package structures;
    
    import java.util.LinkedList;
    import java.util.Stack;
    
    /**
     * 左子树小于该节点 右子树大于该节点 重复元素不添加
     *
     * @param <E>
     */
    public class BST<E extends Comparable<E>> {
        private class Node {
            public E e;
            public Node left;
            public Node right;
    
            public Node(E e) {
                this.e = e;
                left = null;
                right = null;
            }
        }
    
        private int size;
        private Node root;
    
        public BST() {
            size = 0;
            root = null;
        }
    
        public int getSize() {
            return size;
        }
    
        public boolean isEmpty() {
            return size == 0;
        }
    
        /**
         * //向二分搜索树中添加元素
         * public void add(E e) {
         * if (root == null) {
         * root = new Node(e);
         * size ++;
         * } else {
         * add(root, e);
         * }
         * }
         * <p>
         * <p>
         * * 使用递归的逻辑添加元素
         * * 递归终止的条件
         * * 1 添加的元素已存在
         * * 2 添加的元素小于该节点且其左子树为null
         * * 3 添加的元素大于该节点且其右子树为null
         * private void add(Node root, E e) {
         * if (root.e.equals(e)) {
         * return;
         * } else if (e.compareTo(root.e) < 0 && root.left == null) {
         * root.left = new Node(e);
         * size ++;
         * return;
         * } else if (e.compareTo(root.e) > 0 && root.right == null ) {
         * root.right = new Node(e);
         * size ++;
         * return;
         * }
         * <p>
         * if (e.compareTo(root.e) < 0) {
         * add(root.left, e);
         * }else {
         * add(root.right, e);
         * }
         * }
         */
    
        //使用递归 考虑到根节点为null的情况
        public void add(E e) {
            root = add(root, e);
        }
    
        /**
         * 当该节点子树为Null时作为返回条件
         *
         * @param node
         * @param e
         * @return
         */
        private Node add(Node node, E e) {
            if (node == null) {
                node = new Node(e);
                size++;
                return node;
            }
    
            if (e.compareTo(node.e) < 0) {
                node.left = add(node.left, e);
            } else if (e.compareTo(node.e) > 0) {
                node.right = add(node.right, e);
            }
    
            return node;
        }
    
        //查找是否包含该元素
        public boolean contains(E e) {
            return contains(root, e);
        }
    
        private boolean contains(Node node, E e) {
            if (node == null) {
                return false;
            }
    
            if (e.compareTo(node.e) == 0) {
                return true;
            } else if (e.compareTo(node.e) < 0) {
                return contains(node.left, e);
            } else /*e.compareTo(node.e) > 0*/ {
                return contains(node.right, e);
            }
        }
    
        //前序遍历
        public void preOrder() {
            preOrder(root);
        }
    
        private void preOrder(Node node) {
    
            /**
             *       5
             *      / \
             *     3   8
             *    / \   \
             *   2   4    10
             */
    
            if (node == null) {
                return;
            }
            System.out.println(node.e);
            preOrder(node.left);
            preOrder(node.right);
        }
    
        public void inOrder() {
            inOrder(root);
        }
    
        private void inOrder(Node node) {
            if (node == null) {
                return;
            }
    
            inOrder(node.left);
            System.out.println(node.e);
            inOrder(node.right);
        }
    
        //深度优先
        public void preOrderNR() {
            Stack<Node> stack = new Stack<>();
            if (root != null) {
                stack.push(root);
            }
    
            while (!stack.isEmpty()) {
                Node cur = stack.pop();
                System.out.println(cur.e);
                if (cur.right != null) {
                    stack.push(cur.right);
                }
    
                if (cur.left != null) {
                    stack.push(cur.left);
                }
            }
        }
    
        // 层级优先
        public void leverOrder() {
            LinkedList<Node> queue = new LinkedList<>();
            queue.add(root);
    
            while (!queue.isEmpty()) {
                Node cur = queue.remove();
                System.out.println(cur.e);
                if (cur.left != null) {
                    queue.add(cur.left);
                }
                if (cur.right != null) {
                    queue.add(cur.right);
                }
    
            }
        }
    
        public void postOrder() {
            postOrder(root);
        }
    
        private void postOrder(Node node) {
            if (node == null) {
                return;
            }
    
            postOrder(node.left);
            postOrder(node.right);
            System.out.println(node.e);
        }
    
        //获取最小值
        public E minimum() {
            if (size == 0) {
                throw new IllegalArgumentException("BST is empty");
            }
            return minimum(root).e;
        }
    
        private Node minimum(Node node) {
            if (node.left == null) {
                return node;
            }
            return minimum(node.left);
        }
    
        public E maximum() {
            if (size == 0) {
                throw new IllegalArgumentException("BST is empty");
            }
    
            return maximum(root).e;
        }
    
        private Node maximum(Node node) {
            if (node.right == null) {
                return node;
            }
    
            return maximum(node.right);
        }
    
        //删除最小元素节点
        public E removeMin() {
            E minimum = minimum();
            root = removeMin(root);
            return minimum;
        }
    
        //删除最小元素 并返回其右子树
        private Node removeMin(Node node) {
            if (node.left == null) {
                Node rightNode = node.right;
                node.right = null;
                //删除元素维护一下size
                size--;
                return rightNode;
            }
    
            node.left = removeMin(node.left);
            return node;
        }
    
        public E removeMax() {
            E maximum = maximum();
            root = removeMax(root);
            return maximum;
        }
    
        private Node removeMax(Node node) {
            if (node.right == null) {
                Node leftNode = node.left;
                node.left = null;
                size--;
                return leftNode;
            }
    
            node.right = removeMax(node.right);
            return node;
        }
    
        public void remove(E e) {
            root = remove(root, e);
        }
    
        private Node remove(Node node, E e) {
            if (node == null) {
                return null;
            }
            if (e.compareTo(node.e) < 0) {
                node.left = remove(node.left, e);
                return node;
            } else if (e.compareTo(node.e) > 0) {
                node.right = remove(node.right, e);
                return node;
            } else { /*e == node.e*/
                if (node.left == null) {
                    Node rightNode = node.right;
                    node.right = null;
                    size--;
                    return rightNode;
                }
    
                if (node.right == null) {
                    Node leftNode = node.left;
                    node.left = null;
                    size--;
                    return leftNode;
                }
    
                Node successor = minimum(node.right);
                successor.right = removeMin(node.right);
                successor.left = node.left;
                node.right = node.left = null;
    
                return successor;
            }
        }
    
        @Override
        public String toString() {
            StringBuilder stringBuilder = new StringBuilder();
            generateBSTString(root, 0, stringBuilder);
            return stringBuilder.toString();
        }
    
        private void generateBSTString(Node node, int dep, StringBuilder builder) {
            if (node == null) {
                builder.append(generateDep(dep) + "null\n");
                return;
            }
    
            builder.append(generateDep(dep) + node.e + "\n");
            generateBSTString(node.left, dep + 1, builder);
            generateBSTString(node.right, dep + 1, builder);
        }
    
        private String generateDep(int dep) {
    
            StringBuffer stringBuffer = new StringBuffer();
            for (int i = 0; i < dep; i++) {
                stringBuffer.append("--");
            }
    
            return stringBuffer.toString();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:实现一个二分搜索树

          本文链接:https://www.haomeiwen.com/subject/olvoiqtx.html