1. 程式人生 > 其它 >java實現二叉平衡樹

java實現二叉平衡樹

1. java 實現二叉平衡樹

/**
 *  二叉平衡樹
 *  規則:
 *      1.新節點預設的深度為1
 *      2.左子樹和右子樹高度相差超過1 就是不平衡,需要進行旋轉操作
 *          右旋操作
 *          2.1 如果左左節點比左右節點高,那要先對左節點左旋,再對當前節點右旋。否則直接當前節點右旋。
 *          左旋操作
 *          2.2 如果右左節點高於右右節點,需要先對右點節點右旋,再對當前節點左旋。否則直接當前節點左旋。
 *
 */

public class MyAVLTree {
    Integer data;   // 資料
    Integer depth;  // 深度  初始時預設為1
    MyAVLTree leftChild;  // 左子樹
    MyAVLTree rightChild;  // 右子樹
    MyAVLTree parent;    // 父子樹

    public MyAVLTree(Integer data) {
        this.data = data;
        this.depth = 1;
    }

    // 增
    public void insert(MyAVLTree newMyAVLTree) {
        if (newMyAVLTree.data == data) {
            return;
        }
        // 插入左邊
        if (data > newMyAVLTree.data) {
            if (leftChild == null) {
                leftChild = newMyAVLTree;
                newMyAVLTree.parent = this;
            } else {
                leftChild.insert(newMyAVLTree);
            }
        } else{
            // 插入右邊
            if (rightChild == null) {
                rightChild = newMyAVLTree;
                newMyAVLTree.parent = this;
            } else {
                rightChild.insert(newMyAVLTree);
            }
        }
        // 調節平衡
        adjustBalenced(newMyAVLTree);
    }

    // 調整平衡
    private void adjustBalenced(MyAVLTree newMyAVLTree) {
        newMyAVLTree.depth = getDepth(newMyAVLTree) ;


        // 父節點左子樹和右子樹深度對比,如果平衡,則再遞迴檢查父
        if (checkedBalanced(newMyAVLTree)) {
            // null是根節點
            if (newMyAVLTree.parent == null) {
                return;
            }
            adjustBalenced(newMyAVLTree.parent);
            return;
        }

        // 1.如果左左節點比左右節點高,那要先對左節點左旋,再對當前節點右旋。否則直接當前節點右旋。
        if (getDepth(newMyAVLTree.leftChild) > getDepth(newMyAVLTree.rightChild)) {
            //
            if (getDepth(newMyAVLTree.leftChild.leftChild) < getDepth(newMyAVLTree.leftChild.rightChild)) {
                leftRevolve(newMyAVLTree.leftChild);
                rightRevolve(newMyAVLTree);
            } else {
                rightRevolve(newMyAVLTree);
            }
            adjustBalenced(newMyAVLTree);
            return;
        }
        // 如果右左節點高於右右節點,需要先對右點節點右旋,再對當前節點左旋。否則直接當前節點左旋。
        if (getDepth(newMyAVLTree.leftChild) < getDepth(newMyAVLTree.rightChild)) {
            if (getDepth(newMyAVLTree.rightChild.leftChild) > getDepth(newMyAVLTree.rightChild.rightChild)) {
                rightRevolve(newMyAVLTree.rightChild);
                leftRevolve(newMyAVLTree);
            } else {
                leftRevolve(newMyAVLTree);
            }
            adjustBalenced(newMyAVLTree);
        }
    }

    // 右旋
    private void rightRevolve(MyAVLTree newMyAVLTree) {
        final MyAVLTree parent = newMyAVLTree.parent;
        final MyAVLTree leftChild = newMyAVLTree.leftChild;
        if (parent != null) {
            parent.rightChild = leftChild;
        }
        newMyAVLTree.parent = leftChild;
        newMyAVLTree.leftChild = newMyAVLTree.leftChild.rightChild;
        newMyAVLTree.depth = getDepth(newMyAVLTree);
        leftChild.parent = parent;
        leftChild.rightChild = newMyAVLTree;
        leftChild.depth = getDepth(leftChild) ;

    }
    // 左旋
    private void leftRevolve(MyAVLTree myAVLTree) {
        MyAVLTree right = myAVLTree.rightChild;
        final MyAVLTree parent = myAVLTree.parent;

        if (parent != null) {
            parent.leftChild = right;
        }
        myAVLTree.parent = right;
        myAVLTree.rightChild = myAVLTree.rightChild.leftChild;
        myAVLTree.depth = getDepth(myAVLTree);
        right.parent = parent;
        right.leftChild = myAVLTree;
        right.depth = getDepth(right) ;
    }

    // 檢查節點的左右子樹是否平衡
    private boolean checkedBalanced(MyAVLTree myAVLTree) {
        return Math.abs(getDepth(myAVLTree.leftChild) - getDepth(myAVLTree.rightChild)) <=1;
    }

    // 得出節點的深度
    private Integer getDepth(MyAVLTree newMyAVLTree) {
        if (newMyAVLTree == null) {
            return 1;
        }
        MyAVLTree left = newMyAVLTree.leftChild;
        MyAVLTree right = newMyAVLTree.rightChild;

        if (left == null && right == null) {
            return 1;
        }
        if (left == null && right != null) {
            return right.depth + 1;
        }
        if (left != null && right == null) {
            return left.depth + 1;
        }
        return left.depth > right.depth ? left.depth + 1 : right.depth + 1;
    }

    // 查詢root 節點
    public MyAVLTree getRoot() {
        if (parent == null) {
            return this;
        }
        return parent.getRoot();
    }
    // 當前節點是否為父節點
    private Boolean isRoot(MyAVLTree myAVLTree) {
        return myAVLTree.parent == null;
    }

    // 刪
    public Boolean del(Integer integer) {
        if (integer == null) {
            return false;
        }
        MyAVLTree delAVLTree = this.find(integer);
        if (delAVLTree == null) {
            return false;
        }

        MyAVLTree delParent = delAVLTree.parent;
        MyAVLTree left = delAVLTree.leftChild;
        MyAVLTree right = delAVLTree.rightChild;

        // 左右都沒
        if (left == null && right == null) {
            if (delParent == null) {
                // 即當前樹僅一個節點,且刪除的就是這個節點
                return true;
            }
            if (delAVLTree.equals(delParent.leftChild)) {
                delParent.leftChild = null;
            } else {
                delParent.rightChild = null;
            }
            adjustBalenced(delParent);
            return true;
        }
        // 左沒 右有
        if (left == null && right != null) {
            if (delParent == null) {
                right.parent = null;
                return true;
            }
            delParent.rightChild = right;
            adjustBalenced(right);
            return true;
        }
        // 左沒 右有
        if (left != null && right == null) {
            if (delParent == null) {
                left.parent = null;
                return true;
            }
            delParent.leftChild = left;
            adjustBalenced(left);
            return true;
        }
        // 兩邊都有
        final MyAVLTree rightTemp= left.rightChild;
        left.rightChild = right;
        left.parent = delParent;
        right.parent = left;
        if (rightTemp != null) {
            left.insert(rightTemp);
        } else {
            adjustBalenced(left);
        }
        return true;

    }

    // 查
    public MyAVLTree find(Integer value) {
        if (isRoot(this)) {
            findTree(value);
        }
        return getRoot().findTree(value);
    }
    // 從根節點開始查詢元素
    private MyAVLTree findTree(Integer value) {
        if (this.data == value) {
            return this;
        }
        if (this.data > value && this.leftChild != null) {
            return this.leftChild.findTree(value);
        }
        if (this.data < value && this.rightChild != null) {
            return this.rightChild.findTree(value);
        }
        return null;
    }

}

 

有個缺點,不能刪除自己