java实现二叉查找树

java实现二叉查找树

public class BinarySortTree<K extends Comparable<K>, V> {

    public BinaryNode<K, V> getRoot() {
        return root;
    }

    public void setRoot(BinaryNode<K, V> root) {
        this.root = root;
    }

    private BinaryNode<K, V> root;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class BinaryNode<K, V> {
        private K key;
        private V value;
        private BinaryNode<K, V> left;
        private BinaryNode<K, V> right;

        public BinaryNode(K key, V value) {
            this.key = key;
            this.value = value;
        }

//        @Override
//        public String toString() {
//            return "BinaryNode{" +
//                    "key=" + key +
//                    ", value=" + value +
//                    '}';
//        }
    }

    /**
     * 二叉排序树的搜索,最小时间复杂度lg2(n)
     * 1.key小于当前节点则递归向左,大于递归向右,等于返回value
     * 2.递归到最后也没有找到则返回null
     *
     * @param key
     * @return
     */
    public V search(K key) {
        BinaryNode<K, V> cursor = this.root;
        if (cursor == null) {
            return null;
        }
        while (cursor != null) {
            K k = cursor.key;
            if (key.compareTo(k) < 0) {
                cursor = cursor.left;
            } else if (key.compareTo(k) > 0) {
                cursor = cursor.right;
            } else {
                return cursor.value;
            }
        }
        return null;

    }

    /**
     * 插入-非递归
     * 1.先判断根节点是否为空,为空则构造根节点
     * 2.如果根节点不为空,则判断待插入数据与根节点大小
     * 3.如果value小于根,则向左,否则向右,如果等于,则数据已存在不需要处理
     * 4.如果左为空,则用value构造左,右为空则构造右
     *
     * @param value
     * @return
     */
    public void insert(K key, V value) {
        if (root == null) {
            root = new BinaryNode<>(key, value);
            return;
        }

        BinaryNode<K, V> cursor = root;
        while (true) {
            K k = cursor.key;
            if (key.compareTo(k) < 0) {
                if (cursor.left == null) {
                    cursor.left = new BinaryNode<>(key, value);
                    return;
                }
                cursor = cursor.left;
            } else if (key.compareTo(k) > 0) {
                if (cursor.right == null) {
                    cursor.right = new BinaryNode<>(key, value);
                    return;
                }
                cursor = cursor.right;
            } else {
                cursor.value = value;
            }
        }

    }

    /**
     * 删除的情况比较复杂,分为几种情况:
     * 1.叶子节点,无左右孩子,直接将cursor的父节点的孩子cursor设为null
     * 2.有左孩子,没有右孩子,将左孩子拉到自己的位置
     * 3.有右孩子,没有左孩子,将右孩子拉到自己的位置
     * 4.有左右孩子,获取左孩子的最大节点(肯定是叶子节点),放在自己的位置,然后将原节点删除
     *
     * @param key
     */
    public void remove(K key) {
        BinaryNode<K, V> cursor = this.root;
        if (cursor == null) {
            return;
        }
        BinaryNode<K, V> cursorParent = null;
        while (cursor != null) {
            K k = cursor.key;
            if (key.compareTo(k) < 0) {
                cursorParent = cursor;
                cursor = cursor.left;
            } else if (key.compareTo(k) > 0) {
                cursorParent = cursor;
                cursor = cursor.right;
            } else {
                doRemove(cursorParent, cursor);
                return;
            }
        }
    }

    private void doRemove(BinaryNode<K, V> cursorParent, BinaryNode<K, V> cursor) {

        if (cursor.left == null && cursor.right == null) {

            if (cursor == cursorParent.left) {
                cursorParent.left = null;
            } else {
                cursorParent.right = null;
            }
        } else if (cursor.right == null) {
            if (cursor == cursorParent.left) {
                cursorParent.left = cursor.left;
            } else {
                cursorParent.right = cursor.left;
            }
        } else if (cursor.left == null) {
            if (cursor == cursorParent.left) {
                cursorParent.left = cursor.right;
            } else {
                cursorParent.right = cursor.right;
            }
        } else {
            //左右都不为null
            //选择左子树最大节点,放在自己的位置
            //左子树最大节点删除
            BinaryNode<K, V> maxLeft = findMax(cursor.left);
            remove(maxLeft.key);
            cursor.setKey(maxLeft.key);
            cursor.setValue(maxLeft.value);
        }
    }

    public BinaryNode<K, V> findMax(BinaryNode<K, V> root) {
        if (root == null) {
            return null;
        }
        BinaryNode<K, V> cursor = root;
        while (true) {
            if (cursor.right == null) {
                return cursor;
            } else {
                cursor = cursor.right;
            }
        }
    }

    public BinaryNode<K, V> findMin(BinaryNode<K, V> root) {
        if (root == null) {
            return null;
        }
        BinaryNode<K, V> cursor = root;
        while (true) {
            if (cursor.left == null) {
                return cursor;
            } else {
                cursor = cursor.left;
            }
        }
    }

    /**
     * 中根遍历-递归实现
     *
     * @param t
     */
    public void midOrder(BinaryNode<K, V> t) {
        if (t == null) {
            return;
        }
        midOrder(t.left);
        System.out.println(t);
        midOrder(t.right);
    }

    public static void main(String[] args) {
        BinarySortTree<Integer, Integer> tree = new BinarySortTree<>();

        tree.insert(3, 3);
        tree.insert(1, 1);
        tree.insert(2, 2);
        tree.insert(4, 4);
        tree.insert(5, 5);
        System.out.println(tree.getRoot());
        tree.remove(3);
        System.out.println(tree.getRoot());
        tree.remove(4);
        System.out.println(tree.getRoot());
        tree.remove(5);
        System.out.println(tree.getRoot());
    }
}

 

posted @ 2021-10-08 14:10  Mars.wang  阅读(54)  评论(0编辑  收藏  举报