平衡搜索二叉树实现

Posted INnoVation-V2

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平衡搜索二叉树实现相关的知识,希望对你有一定的参考价值。

public class BBST<Key extends Comparable<Key>, Value> {
    private Node root;

    public class Node {
        private Key key;
        private Value val;
        private Node parent, left, right;
        private int height;
        private int bfc;   //balance factor

        private Node(Key key, Value val, int height, Node parent, int bfc) {
            this.key = key;
            this.val = val;
            this.height = height;
            this.parent = parent;
            this.left = this.right = null;
            this.bfc = bfc;
        }
    }

    public Value Search(Key key) {
        return SearchIn(root, key);
    }

    private Value SearchIn(Node t, Key key) {
        if (t == null)
            return null;
        else if (key.compareTo(t.key) == 0)
            return t.val;
        return SearchIn(key.compareTo(t.key) < 0 ? t.left : t.right, key);
    }

    private void connect34(Node a, Node b, Node c, Node t0, Node t1, Node t2, Node t3) {
        b.left = a;
        b.right = c;
        a.parent = b;
        c.parent = b;
        a.left = t0;
        if (t0 != null)
            t0.parent = a;
        a.right = t1;
        if (t1 != null)
            t1.parent = a;
        c.left = t2;
        if (t2 != null)
            t2.parent = c;
        c.right = t3;
        if (t3 != null)
            t3.parent = c;
        root = b;
    }

    private void UpdateHeight_BFC(Node x) {
        Node x2 = x;
        while (true) {
            if (x.left == null && x.right == null) {
                x.height = 0;
                x.bfc = 0;
            } else if (x.left == null)
                x.height = x.right.height + 1;
            else if (x.right == null) {
                x.height = x.left.height + 1;
                System.out.println(" ");
            } else
                x.height = (x.left.height == x.right.height ? x.left.height : x.left.height > x.right.height ? x.left.height : x.right.height) + 1;
            if (x.parent == null)
                break;
            else
                x = x.parent;
        }
        while (x2 != null) {
            if (x2.left == null && x2.right == null) {
            } else if (x2.left == null)
                x2.bfc = 0 - x2.height;
            else if (x2.right == null)
                x2.bfc = x2.height;
            else {
                x2.bfc = x2.left.height - x2.right.height;
            }
            x2 = x2.parent;
        }
        root = x;
    }

    private boolean Balanced(Node t) {
        return t.bfc < 2 && t.bfc > -2;
    }

    private void ReBalance(Node t) {
        while (t != null) {
            if (!Balanced(t)) {
                Node son = null, grandson = null;
                if (t.bfc > 1) { //左子树不平衡
                    son = t.left;
                    if (son.bfc < 0) {           //左右
                        if (t.parent != null) {
                            if (t.parent.left != null && t.parent.left.key == t.key)
                                t.parent.left = son.right;
                            else
                                t.parent.right = son.right;
                            son.right.parent = t.parent;
                        }
                        son.right.parent = null;
                        connect34(son, son.right, t, son.left, son.right.left, son.right.right, t.right);
                        UpdateHeight_BFC(t);
                        UpdateHeight_BFC(son);
                        break;
                    } else {                       //左左
                        if (t.parent != null) {
                            if (t.parent.left != null && t.parent.left.key == t.key)
                                t.parent.left = son;
                            else
                                t.parent.right = son;
                            son.parent = t.parent;
                        }
                        son.parent = null;
                        connect34(son.left, son, t, son.left.left, son.left.right, son.right, t.right);
                        UpdateHeight_BFC(t);
                        UpdateHeight_BFC(son.left);
                        break;
                    }
                } else {         //右子树不平衡
                    son = t.right;
                    if (son.bfc < 0) {                    //右右
                        if (t.parent != null) {
                            if (t.parent.left != null && t.parent.left.key == t.key)
                                t.parent.left = son;
                            else
                                t.parent.right = son.left;
                            son.parent = t.parent;
                        }
                        son.parent = null;
                        connect34(t, son, son.right, t.left, son.left, son.right.left, son.right.right);
                        UpdateHeight_BFC(t);
                        UpdateHeight_BFC(son.right);
                        break;
                    } else {                    //右左
                        if (t.parent != null) {
                            if (t.parent.left != null && t.parent.left.key == t.key)
                                t.parent.left = son.left;
                            else
                                t.parent.right = son.left;
                            son.left.parent = t.parent;
                        }
                        son.left.parent = null;
                        connect34(t, son.left, son, t.left, son.left.left, son.left.right, son.right);
                        UpdateHeight_BFC(t);
                        UpdateHeight_BFC(son);
                        break;
                    }
                }
            }
            t = t.parent;
        }
    }


    public void Insert(Key key, Value val) {
        if (root == null) {
            root = new Node(key, val, 0, null, 0);
            return;
        }
        Node temp = root;
        while (true) {
            int cmp = key.compareTo(temp.key);
            if (cmp < 0) {
                if (temp.left == null) {
                    temp.left = new Node(key, val, 0, temp, 0);
                    UpdateHeight_BFC(temp);
                    ReBalance(temp);
                    return;
                } else
                    temp = temp.left;
            } else if (cmp > 0) {
                if (temp.right == null) {
                    temp.right = new Node(key, val, 0, temp, 0);
                    UpdateHeight_BFC(temp);
                    ReBalance(temp);
                    return;
                } else
                    temp = temp.right;
            } else {
                temp.val = val;
                return;
            }
        }
    }

    public void Remove(Key key) {
        Node temp_root = root;
        if (root == null || key == null)
            return;
        while (temp_root != null) {
            int cmp = key.compareTo(temp_root.key);
            if (cmp > 0)
                temp_root = temp_root.right;
            else if (cmp < 0)
                temp_root = temp_root.left;
            else {
                if (temp_root.left == null || temp_root.right == null) {
                    if (temp_root.left != null) {
                        temp_root.key = temp_root.left.key;
                        temp_root.val = temp_root.left.val;
                        temp_root.left = temp_root.left.left;
                        temp_root.right = temp_root.left.right;
                    } else if (temp_root.right != null) {
                        System.out.println(" ");
                        temp_root.key = temp_root.right.key;
                        temp_root.val = temp_root.right.val;
                        temp_root.left = temp_root.right.left;
                        temp_root.right = temp_root.right.right;
                    } else {
                        temp_root = temp_root.parent;
                        if (temp_root.left != null && temp_root.left.key == key)
                            temp_root.left = null;
                        else
                            temp_root.right = null;
                    }
                    UpdateHeight_BFC(temp_root);
                    ReBalance(temp_root);
                } else {
                    Node t = temp_root.right;
                    while (t.left != null)
                        t = t.left;
                    temp_root.key = t.key;
                    temp_root.val = t.val;
                    if (t.right != null) {
                        t.key = t.right.key;
                        t.val = t.right.val;
                        t.left = t.right.left;
                        t.right = t.right.right;
                    } else {
                        t.parent.left = null;
                    }
                    UpdateHeight_BFC(t);
                    ReBalance(t);
                }
            }
        }
    }

    public static void main(String args[]) {
        BBST<Integer, Integer> t = new BBST<Integer, Integer>();
        t.Insert(50, 1);
        t.Insert(60, 4);
        t.Insert(40, 2);
        t.Insert(30, 3);
        t.Remove(60);
        System.out.println("断点设置处");
    }
}

 

以上是关于平衡搜索二叉树实现的主要内容,如果未能解决你的问题,请参考以下文章

红黑树——一个自平衡的二叉搜索树

平衡二叉树的java实现

平衡搜索二叉树实现

平衡二叉树的删除

进一步理解平衡二叉树(插入)

用二分搜索树(BST)实现平衡二叉树(AVL)