Coding/자료구조

[자료구조] AVL 트리

ryureeru 2022. 10. 2. 15:43

AVL 트리

 

  • 노트가 삽입, 삭제될 때 트리의 균형을 체크하고 유지하는 트리
  • 각 노드의 BF (Balance Factor : 왼쪽 서브 트리 높이 - 오른쪽 서브 트리 높이)를 [-1, 0, 1]만 가지게 하여 균형 유지 
  • 균형이 깨진 경우 BF가 +/- 면 왼/오른쪽 서브 트리에 이상
  • 회전 연산 : 단순 회전(LL, RR), 이중 회전(LR, RL)

 

 

1. LL (Left-Left)

 

  • 회전 1회
  • 오른쪽 방향으로 회전

 

 

2. RR (Right-Right)

 

  • 회전 1회
  • 왼쪽 방향으로 회전

 

 

3. LR (Left-Right)

 

  • 회전 2회
  • RR 회전 후 LL 회전

 

 

4. RL (Right-Left)

 

  • 회전 2회
  • LL 회전 후 RR 회전

 

 

public Node rightRotate(Node node) {
        Node lNode = node.left;

        node.left = lNode.right;
        lNode.right = node;

        node.height = Math.max(height(node.left), height(node.right)) + 1;
        lNode.height = Math.max(height(lNode.left), height(lNode.right)) + 1;

        return lNode;
}

 public Node leftRotate(Node node) {
        Node rNode = node.right;

        node.right = rNode.left;
        rNode.left = node;

        node.height = Math.max(height(node.left), height(node.right)) + 1;
        rNode.height = Math.max(height(rNode.left), height(rNode.right)) + 1;

        return rNode;
}

public Node lrRotate(Node node) {
    node.left = leftRotate(node.left);
    return rightRotate(node);
}

public Node rlRotate(Node node) {
    node.right = rightRotate(node.right);
    return leftRotate(node);
}

public int getBalance(Node node) {
    if (node == null) {
        return 0;
    }

    return height(node.left) - height(node.right);
}

 

public Node insert(Node node, int key) {
        if (node == null) {
            return new Node(key, null, null);
        }

        if (key < node.key) {
            node.left = insert(node.left, key);
        } else {
            node.right = insert(node.right, key);
        }

        node.height = Math.max(height(node.left), height(node.right)) + 1;

        int balance = getBalance(node);
        // LL
        if (balance > 1 && key < node.left.key) {
            return rightRotate(node);
        }

        // RR
        if (balance < -1 && key > node.right.key) {
            return leftRotate(node);
        }

        // LR
        if (balance > 1 && key > node.left.key) {
            return lrRotate(node);
        }

        // RL
        if (balance < -1 && key < node.right.key) {
            return rlRotate(node);
        }

        return node;
}

 

public Node delete(Node node, int key) {
        if (node == null) {
            return null;
        }

        if (key < node.key) {
            node.left = delete(node.left, key);
        } else if (key > node.key) {
            node.right = delete(node.right, key);
        } else {
            if (node.left == null) {
                return node.right;
            } else if (node.right == null) {
                return node.left;
            } else {
                Node predecessor = node;
                Node successor = node.left;

                while (successor.right != null) {
                    predecessor = successor;
                    successor = successor.right;
                }

                predecessor.right = successor.left;
                node.key = successor.key;
            }
        }

        node.height = Math.max(height(node.left), height(node.right)) + 1;

        int balance = getBalance(node);
        // LL
        if (balance > 1 && getBalance(node.left) > 0) {
            return rightRotate(node);
        }

        // RR
        if (balance < -1 && getBalance(node.right) < 0) {
            return leftRotate(node);
        }

        // LR
        if (balance > 1 && getBalance(node.left) < 0) {
            return lrRotate(node);
        }

        // RL
        if (balance < - 1 && getBalance(node.right) > 0) {
            return rlRotate(node);
        }

        return node;
}

 

 

'Coding > 자료구조' 카테고리의 다른 글

[자료구조] Heap  (0) 2022.10.08
[자료구조] 그래프 탐색  (0) 2022.10.02
[자료구조] 이진 트리의 순회  (0) 2022.10.01
[자료구조] 해시 테이블  (0) 2022.10.01
[자료구조] Deque  (0) 2022.10.01