zoukankan      html  css  js  c++  java
  • 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());
        }
    }
  • 相关阅读:
    [bzoj] 2565 最长双回文串
    [codeforces] 17E Palisection
    luogu P3267 [JLOI2016/SHOI2016] 侦查守卫
    181020-181021 模拟 题解
    luogu P2571 [SCOI2010]传送带
    poj1064 Cable master
    poj1422 Air Raid
    luogu P2512 [HAOI2008]糖果传递
    CF549H Degenerate Matrix
    左偏树基础教学
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15379529.html
Copyright © 2011-2022 走看看