
2025.04.18
오늘한 내용 : 고급 자료 구조 :RED-BLACK-TREE 개념 정리
WEEK06: 메모리 누수, 균형 이진 탐색 트리(AVL Tree, Red-Black Tree)
너무 너무 헷갈린다. 고려해야 할 점이 너무 많음!

일반적인 이진 검색 트리와 레드 블랙 트리
일반적인 이진 탐색 트리는 삽입 순서에 따라 한쪽으로 치우칠 수 있어 최악의 경 우 O(n)의 성능을 가짐.
RB트리는 자동으로 균형을 맞추기 때문에 항상 O(log n)의 시간 복잡도를 보장.
1. 노드는 빨강 또는 검정이다.
2. 루트는 항상 검정이다.
3. 모든 리프(NIL)는 검정이다. (리프는 실제 데이터가 아닌 NULL 포인터)
4. 빨강 노드의 자식은 반드시 검정이다. (빨강이 연속될 수 없음)
5. 어떤 노드에서 리프까지 가는 모든 경로에는 같은 수의 검정 노드가 있다.
이 속성들을 지키면서 노드 삽입/삭제 시마다 자동으로 트리를 재조정(회전 및 색상 변경)하여 균형을 유지.
| 연산 | 시간 복잡도 |
|---|---|
| 검색 | O(log n) |
| 삽입 | O(log n) |
| 삭제 | O(log n) |
레드 블랙 트리 특성에 따라 부모 노드 p가 레드라면 부모 노드 p의 부모 p² 는 반드시 블랙이다.
레드 블랙 트리 특성에 따라 x의 형제 노드도 반드시 블랙이다. (Rule 4)
x 주변에서 레드와 블랙 두 가지 다 가능한 것은 p의 형제 노드 s(x의 삼촌 노드) 뿐이다.
x의 부모노드(p)가 Red
Case 1) x의 삼촌노드(s)가 Red
Red → BlackRed로Black으로 (Rule 2) (p² is not root)
-----------------------------------------------------
삽입 전 (Red-Red 위반 발생) 수선 후 (색상 변경)
/ /
[B] p² [R] p²
/ \ / \
[R] p [R] s ===> [B] p [B] s
/ /
[R] x [R] xCase 2) s가 Black 또는 NULL
Case 2-1: x가 오른쪽 자식
(좌회전 전)
[B] p²
/
[R] p
\
[R] x
-- 좌회전 (p 중심) -->
Case 2-2 구조로 변경
(이제 x가 p²의 왼쪽 자식)
[B] p²
/
[R] x
/
[R] p
-- 우회전 (p² 중심) & 색상 교환(p²와 회전 후 p² 위 올라온 노드) -->
최종 구조 (Red-Black 속성 회복)
[B] x
/ \
[R] p [R] p²
트리의 일부 구조를 재배열하여 이진 탐색 트리의 성질을 유지하면서, 균형을 맞추는 연산.
| 종류 | 기준 노드 | 결과 방향 |
|---|---|---|
| 좌회전 (Left Rotation) | 현재 노드 | 오른쪽 자식이 위로 올라감 |
| 우회전 (Right Rotation) | 현재 노드 | 왼쪽 자식이 위로 올라감 |
def left_rotate(p):
x = p.right
p.right = x.left # ← 서브트리 재배치
x.left = p
# 부모 포인터 업데이트 등 추가
def right_rotate(p2):
p = p2.left
p2.left = p.right # ← 서브트리 재배치
p.right = p2
# 부모 포인터 업데이트 등 추가
삭제는 BST 삭제 방식 + RB트리 규칙 수선 작업의 결합.
| Case | 삭제 노드 색 | 조건 | 주요 동작 |
|---|---|---|---|
| Case 0 | 🔴 RED | 자식이 있든 없든 | 그냥 삭제만 하면 됨. 수선 불필요 |
| Case 1 | ⚫ BLACK | 형제(s)가 RED | s↔p 색 교환 → p 기준 회전 → 새로운 형제로 Case 2~4 적용 |
| Case 2 | ⚫ BLACK | 형제(s)가 BLACK, 형제의 자식 둘 다 BLACK | (1) 부모(p)가 RED :형제를 RED, 부모를 BLACK으로 바꾸면 DB가 완전히 해소 → 종료 //// (2) 부모(p)가 BLACK:형제를 RED, DB를 한 단계 위(parent)로 전이 → 다시 Case 1~4 검사 |
| Case 3 | ⚫ BLACK | 형제 BLACK, 가까운 자식이 RED | s 기준 회전 → 가까운 자식 ↔ s 색 교환 → Case 4로 전환 |
| Case 4 | ⚫ BLACK | 형제 BLACK, 먼 자식이 RED | p↔s 색 교환 → p 기준 회전 → 먼 자식을 BLACK으로 칠하면 DB 해소 → 종료 |
초기 트리:
[B]10
/ \
[B] 5 [R]15
/ \
[B]12 [B]20
[B]5 → 왼쪽 자리 NIL에 Double Black 발생NIL처리:
10→R, 15→B [B]15
/ \
[R]10 [B]20
/ \
[BB]NIL [B]12
처리:
12→RED, 10→BLACK → DB 해소 → 종료 [B]15
/ \
[B]10 [B]20
\
[R]12
참고: 본 예시에서는 Case 3·4가 전혀 발생하지 않습니다.
초기 트리:
[B]8
/ \
[B]3 [B]12
/ \ / \
[B]1 [B]6 [B]10 [B]14
/ \
[R]4 [R]7
[B]1 → 3의 왼쪽 자리 NIL에 Double Black 발생처리:
6 ↔ 4 → 6(R), 4(B)6 기준 우회전 [B]8
/ \
[B]3 [B]12
/ \ / \
[BB]NIL [B]4 [B]10 [B]14
\
[R]6
\
[R]7
처리:
3 ↔ 4 (둘 다 B → 변화 없음)3 기준 좌회전BLACK [B]8
/ \
[B]4 [B]12
/ \ / \
[B]3 [B]6 [B]10 [B]14
/ \
[BB]NIL [R]7
[B]8
/ \
[B]4 [B]12
/ \ / \
[B]3 [B]6 [B]10 [B]14
\
[R]7