二叉树实战(一) - 二叉查找树代码实现

/**
 * 二叉查找树
 *
 * @param <Key>
 * @param <Value>
 */
public class BinaryTree<Key extends Comparable<Key>, Value> {

    /********************************************
     *  二叉查找树,实现核心功能
     * 1.插入
     * 2.查找
     * 3.删除
     * 4.查询最小值
     * 5.查询最大值
     ********************************************/

    // 记录根节点
    private Node root;

    // 记录树中元素的个数
    private int N;

    /**
     * 树节点结构体类
     */
    private class Node {

        public Key key;  // 存储键
        public Value value;  //  存储值
        public Node left;  // 记录左子节点
        public Node right; // 记录右子节点

        public Node(Key key, Value value, Node left, Node right) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }

    // 获取树中元素的个数
    public int getSize() {
        return N;
    }

    // 向树中添加元素 key-value
    public void put(Key key, Value value) {
        root = put(root, key, value);
    }

    // 向指定的树x中添加key-value,并返回添加元素后的新树
    private Node put(Node x, Key key, Value value) {
        //  如果x的子树为空
        if (x == null) {
            N++;
            return new Node(key, value, null, null);
        }
        // 如果x的子树不为空,则比较x节点的键和key的大小
        // 如果key小于x结点的键,则继续找x结点的左子树。如果key大于x结点的键,则继续找x结点的右子树,如果key等于x结点的键,则替换x结点的值为value即可。
        int cmp = key.compareTo(x.key);
        if (cmp > 0) {
            x.right = put(x.right, key, value);
        } else if (cmp < 0) {
            x.left = put(x.left, key, value);
        } else {
            x.value = value;
        }
        return x;
    }

    // 查询树中指定的key对应的value
    public Value get(Key key) {
        return get(root, key);
    }

    // 从指定的树x中,查找key对应的值
    private Value get(Node x, Key key) {
        // x树为NULL
        if (x == null) {
            return null;
        }
        // x树不为NULL,比较键的大小
        // 如果key小于x结点的键,则继续找x结点的左子树。如果key大于x结点的键,则继续找x结点的右子树,如果key等于x结点的键,则返回该键的值
        int cmp = key.compareTo(x.key);
        if (cmp > 0) {
            return get(x.right, key);
        } else if (cmp < 0) {
            return get(x.left, key);
        } else {
            return x.value;
        }
    }

    // 删除树中key对应的value
    public void delete(Key key) {
        delete(root, key);
    }

    // 删除指定树x中key对应的value,并返回删除后的新树
    private Node delete(Node x, Key key) {
        // x树为null
        if (x == null) {
            return null;
        }
        // x树不为NULL,比较键的大小
        // 如果key小于x结点的键,则继续找x结点的左子树。如果key大于x结点的键,则继续找x结点的右子树,如果key等于x结点的键,执行真正的删除操作
        int cmp = key.compareTo(x.key);
        if (cmp > 0) {
            return x.right = delete(x.right, key);
        } else if (cmp < 0) {
            return x.left = delete(x.left, key);
        } else {
            N--;
            if (x.right == null) {
                return x.left;
            }
            if (x.left == null) {
                return x.right;
            }
            // 找到右子树的最小结点
            Node minNode = x.right;
            while (minNode.left != null) {
                minNode = minNode.left;
            }
            // 删除右子树中最小的结点
            Node n = x.right;
            while (n.left != null) {
                if (n.left.left == null) {
                    n.left = null;
                } else {
                    n = n.left;  // 变换n结点
                }
            }
            // 让x结点的左子树成为minNode的左子树
            minNode.left = x.left;
            // 让x结点的右子树成为minNode的右子树
            minNode.right = x.right;
            // 让x结点的父结点指向minNode
            x = minNode;
            return x;
        }
    }

    // 找出整个树中最小的键
    public Key getMin() {
        return min(root).key;
    }

    // 找到指定树x中最小值的键所在的结点
    private Node min(Node x) {
        if (x.left != null) {
            return min(x.left);
        } else {
            return x;
        }
    }

    // 找出整个树中最大的键
    public Key getMax() {
        return max(root).key;
    }

    // 找到指定树x中最大值的键所在的结点
    private Node max(Node x) {
        if (x.right != null) {
            return max(x.right);
        } else {
            return x;
        }
    }

}

 

posted @ 2020-05-03 12:01  灰色飘零  阅读(397)  评论(0)    收藏  举报