AVL Tree

2025. 8. 8. 22:10·자료 구조

1. 정의

AVL Tree는 모든 노드에 대해 왼쪽과 오른쪽 서브트리의 높이 차이(균형 인수, BF)가 1 이하가 되도록 유지하는 이진 탐색 트리(Binary Search Tree, BST)이다.

1962년, Adelson-Velsky와 Landis가 고안하였다.


2. 기본 속성

(1) BST 규칙

  • 모든 노드는 왼쪽 자식 < 현재 노드 < 오른쪽 자식의 조건을 만족

(2) 높이 균형 조건

  • 모든 노드에 대해 |높이(왼쪽) - 높이(오른쪽)| ≤ 1
  • 이 조건을 유지하면 트리의 높이 = O(log n) 으로 유지되어, 검색·삽입·삭제가 효율적

3. 균형 인수 (Balance Factor)

정의

각 노드에 대해 균형 인수 BF는 다음과 같이 계산된다:

BF = height(left subtree) - height(right subtree)
  • BF의 값이 –1, 0, +1이면 균형
  • |BF| > 1 이 되면 불균형 발생 → 회전 필요

4. 회전 연산

(1) LL (Left-Left)

  • 왼쪽 자식의 왼쪽에 삽입 → 오른쪽 회전
     z              y
    /              / \
   y      →       x   z
  /
 x

(2) RR (Right-Right)

  • 오른쪽 자식의 오른쪽에 삽입 → 왼쪽 회전
   z                 y
    \               / \
     y     →       z   x
      \
       x

(3) LR (Left-Right)

  • 왼쪽 자식의 오른쪽에 삽입 → 왼쪽 회전 + 오른쪽 회전
     z             z             x
    /     →       /     →      / \
   y             x           y   z
    \           /
     x         y

(4) RL (Right-Left)

  • 오른쪽 자식의 왼쪽에 삽입 → 오른쪽 회전 + 왼쪽 회전
   z                z               x
    \     →         \     →       / \
     y               x           z   y
    /                 \
   x                   y

5. 삽입 알고리즘

  1. 일반 BST 방식으로 새 노드를 삽입
  2. 삽입 경로를 따라 위로 올라가며 height, BF 재계산
  3. 첫 번째로 불균형이 발생한 노드에서 회전 수행
  4. 시간 복잡도: O(log n)

6. 삭제 알고리즘

  1. 일반 BST 방식으로 삭제
    • 삭제 대상이 자식이 없거나 하나면 바로 삭제
    • 둘 다 있을 경우 후계자 노드로 대체하고 후계자 위치의 노드 삭제
  2. 삭제된 노드의 부모부터 루트까지 올라가며 height, BF 갱신
  3. 불균형 발생 시 회전 수행
    • LL, LR, RR, RL 중 적절한 회전 수행
    • 회전 후에도 부모 노드로 올라가며 계속 검사

7. C 언어 코드 예시

(1) 구조체 정의 및 높이 계산

typedef struct Node {
    int key;
    struct Node *left;
    struct Node *right;
    int height;
} Node;

int height(Node* n) {
    return (n == NULL) ? 0 : n->height;
}

int max(int a, int b) {
    return (a > b) ? a : b;
}

(2) 회전 함수

Node* rightRotate(Node* z) {
    Node* y = z->left;
    Node* T2 = y->right;

    y->right = z;
    z->left = T2;

    z->height = max(height(z->left), height(z->right)) + 1;
    y->height = max(height(y->left), height(y->right)) + 1;

    return y;
}

Node* leftRotate(Node* z) {
    Node* y = z->right;
    Node* T2 = y->left;

    y->left = z;
    z->right = T2;

    z->height = max(height(z->left), height(z->right)) + 1;
    y->height = max(height(y->left), height(y->right)) + 1;

    return y;
}

(3) 균형 인수 계산

int getBalance(Node* n) {
    if (n == NULL) return 0;
    return height(n->left) - height(n->right);
}

(4) 삽입 함수

Node* insert(Node* node, int key) {
    if (node == NULL) {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->key = key;
        newNode->left = newNode->right = NULL;
        newNode->height = 1;
        return newNode;
    }

    if (key < node->key)
        node->left = insert(node->left, key);
    else if (key > node->key)
        node->right = insert(node->right, key);
    else
        return node;  // 중복 키는 허용하지 않음

    node->height = 1 + max(height(node->left), height(node->right));
    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) {
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }

    // RL
    if (balance < -1 && key < node->right->key) {
        node->right = rightRotate(node->right);
        return leftRotate(node);
    }

    return node;
}

(5) 삭제 함수

Node* minValueNode(Node* node) {
    Node* current = node;
    while (current->left != NULL)
        current = current->left;
    return current;
}

Node* deleteNode(Node* root, int key) {
    if (root == NULL)
        return root;

    // BST 삭제, 재귀로 밑바닥까지 보냄(삭제노드 찾을 때 까지)
    if (key < root->key)
        root->left = deleteNode(root->left, key); 
    else if (key > root->key)
        root->right = deleteNode(root->right, key);
    else {
        // 노드 찾음
        if ((root->left == NULL) || (root->right == NULL)) {
            Node* temp = root->left ? root->left : root->right;
            if (temp == NULL) {
                // 자식 없음
                temp = root;
                root = NULL;
            } else {
                // 자식 하나
                *root = *temp;
            }
            free(temp);
        } else {
            // 자식 둘 다 있음
            Node* temp = minValueNode(root->right);
            root->key = temp->key;
            root->right = deleteNode(root->right, temp->key);
        }
    }

    if (root == NULL)
        return root;

    // 높이 갱신
    root->height = 1 + max(height(root->left), height(root->right));

    int balance = getBalance(root);

    // 회전 케이스
    // LL
    if (balance > 1 && getBalance(root->left) >= 0)
        return rightRotate(root);

    // LR
    if (balance > 1 && getBalance(root->left) < 0) {
        root->left = leftRotate(root->left);
        return rightRotate(root);
    }

    // RR
    if (balance < -1 && getBalance(root->right) <= 0)
        return leftRotate(root);

    // RL
    if (balance < -1 && getBalance(root->right) > 0) {
        root->right = rightRotate(root->right);
        return leftRotate(root);
    }

    return root;
}

8. 장점

  • 항상 높이 균형 유지 → 검색, 삽입, 삭제 O(log n) 보장
  • 일반 BST보다 최악의 경우 성능이 훨씬 우수
  • 검색 경로가 짧고 효율적

9. 단점

  • 삽입/삭제 시 회전이 빈번하게 발생 → 구현 복잡도 높음
  • 레드-블랙 트리보다 연산량 많을 수 있음
  • 트리 수정(업데이트) 시 성능 저하가 있을 수 있음
728x90

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

B-Tree  (0) 2025.08.08
RB Tree  (0) 2025.08.08
[Python] 최소 신장 트리(MST) - 크루스칼, 프림 알고리즘  (0) 2025.04.03
[Python] 그래프 기초  (0) 2025.03.29
[Python] 해시 테이블 (Hash Table)  (0) 2025.03.28
'자료 구조' 카테고리의 다른 글
  • B-Tree
  • RB Tree
  • [Python] 최소 신장 트리(MST) - 크루스칼, 프림 알고리즘
  • [Python] 그래프 기초
ahpicl64
ahpicl64
in the clouds
  • ahpicl64
    구름
    ahpicl64
  • 전체
    오늘
    어제
    • 분류 전체보기 (95)
      • WIL (4)
      • Jungle (36)
      • AWS (2)
      • SQL (2)
      • CS:APP (17)
      • Algorithm (10)
      • K8s (7)
      • 자료 구조 (10)
      • Spring (4)
      • React (0)
      • 운영체제 (1)
      • 기타등등 (2)
      • 이야기 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    Spring
    queue
    DB
    컴퓨터시스템
    EC2
    github actions
    DevOps
    CSAPP
    어셈블리
    자료구조
    S3
    IAM
    python
    CloudFront
    트러블슈팅
    부하테스트
    Spring boot
    k8s
    AWS
    알고리즘
  • 02-21 07:23
  • hELLO· Designed By정상우.v4.10.3
ahpicl64
AVL Tree
상단으로

티스토리툴바