Red-Black Tree는 자가 균형 이진 탐색 트리(Self-Balancing Binary Search Tree)의 한 종류입니다.
느슨한 균형(최장 경로 <= 2 * 최단 경로)
메모리 효율성(색상정보 1bit)
시간 복잡도
| 연산 | 최선(Best) | 평균(Average) | 최악(Worst) |
|---|---|---|---|
| 탐색 (Search) | O(log N) | O(log N) | O(log N) |
| 삽입 (Insertion) | O(log N) | O(log N) | O(log N) |
| 삭제 (Deletion) | O(log N) | O(log N) | O(log N) |
위 속성은 최장 경로 <= 2 최단 경로를 보장합니다.
이유는
최단 경로: 모두 Black 노드로만 구성 → 길이 = B
최장 경로: Black과 Red가 교대로 나타남 → 길이 = 2B
속성 4에 의해 모든 경로의 Black 노드 수가 동일하므로
최장 경로 <= 2 최단 경로입니다.
N: 새로 추가된 노드
P: 추가된 노드의 부모 노드
U: 부모 노드의 형제 노드
G: 부모 노드의 부모 노드
(G, B)
/ \
(P, R) (U, R) ← Uncle이 Red
/
(N, R) ← Red-Red 위반!
Step 1: Parent를 Black으로
(G, B)
/ \
(P, B) (U, R)
/
(N, R)
Step 2: Uncle을 Black으로
(G, B)
/ \
(P, B) (U, B)
/
(N, R)
Step 3: Grandparent를 Red로
(G, R) ← 위로 전파 가능
/ \
(P, B) (U, B)
/
(N, R)
(G, R) ← 이제 G를 N으로 보고 위로 올라가서 다시 체크
/ \
(P, B) (U, B)
/
(N, R)
결과: Recoloring만, 회전 없음, 위로 전파 계속
(G, B)
/ \
(P, R) (U, B) ← Uncle이 Black
/
(N, R) ← Red-Red 위반!
Step 1: G를 기준으로 Right Rotation
(P, R)
/ \
(N, R) (G, B)
\
(U, B)
Step 2: Recoloring (P를 Black, G를 Red)
(P, B) ← 새로운 루트
/ \
(N, R) (G, R)
\
(U, B)
(P, B)
/ \
(N, R) (G, R)
\
(U, B)
결과: 1번 회전 + Recoloring, 완료
(G, B)
/ \
(U, B) (P, R) ← Uncle이 Black
\
(N, R) ← Red-Red 위반!
Step 1: G를 기준으로 Left Rotation
(P, R)
/ \
(G, B) (N, R)
/
(U, B)
Step 2: Recoloring (P를 Black, G를 Red)
(P, B) ← 새로운 루트
/ \
(G, R) (N, R)
/
(U, B)
(P, B)
/ \
(G, R) (N, R)
/
(U, B)
결과: 1번 회전 + Recoloring, 완료
(G, B)
/ \
(P, R) (U, B) ← Uncle이 Black
\
(N, R) ← Red-Red 위반!
Step 1: P를 기준으로 Left Rotation
(G, B)
/ \
(N, R) (U, B) ← LL 케이스로 변환!
/
(P, R)
Step 2: G를 기준으로 Right Rotation
(N, R)
/ \
(P, R) (G, B)
\
(U, B)
Step 3: Recoloring (N을 Black, G를 Red)
(N, B) ← 새로운 루트
/ \
(P, R) (G, R)
\
(U, B)
(N, B)
/ \
(P, R) (G, R)
\
(U, B)
결과: 2번 회전 + Recoloring, 완료
(G, B)
/ \
(U, B) (P, R) ← Uncle이 Black
/
(N, R) ← Red-Red 위반!
Step 1: P를 기준으로 Right Rotation
(G, B)
/ \
(U, B) (N, R) ← RR 케이스로 변환!
\
(P, R)
Step 2: G를 기준으로 Left Rotation
(N, R)
/ \
(G, B) (P, R)
/
(U, B)
Step 3: Recoloring (N을 Black, G를 Red)
(N, B) ← 새로운 루트
/ \
(G, R) (P, R)
/
(U, B)
(N, B)
/ \
(G, R) (P, R)
/
(U, B)
결과: 2번 회전 + Recoloring, 완료
| Case | 초기 상태 | Rotation | 최종 상태 | 종료 |
|---|---|---|---|---|
| 1 | Red-Red | 없음 | Recolor 후 전파 | ❌ 계속 |
| 2-1 (LL) | Red-Red (왼-왼) | Right 1회 | 균형 잡힘 | ✅ 완료 |
| 2-2 (RR) | Red-Red (오-오) | Left 1회 | 균형 잡힘 | ✅ 완료 |
| 3-1 (LR) | Red-Red (왼-오) | Left→Right | 균형 잡힘 | ✅ 완료 |
| 3-2 (RL) | Red-Red (오-왼) | Right→Left | 균형 잡힘 | ✅ 완료 |
핵심 패턴:
Black 노드를 삭제하면 발생하는 문제:
Before:
(B)
/ \
(B) (B) ← 이 Black 노드를 삭제
/ \ / \
N N N N
After:
(B)
/ \
(B) (DB) ← Double Black! (Black 카운트가 2개)
/ \
N N
문제: 왼쪽 경로는 Black 2개, 오른쪽 경로는 Black 1개 → Property 4 위반!
목표: Double Black을 Single Black으로 만들기
X: 제거해야할 노드
S: 제거해야할 노드의 형제 노드
P: 제거해야할 노드의 부모 노드
(P, B)
/ \
(X, DB) (S, R) ← Sibling이 Red!
/ \
(C1,B) (C2,B)
Step 1: P를 기준으로 Left Rotation
(S, R)
/ \
(P, B) (C2,B)
/ \
(X,DB)(C1,B)
Step 2: Recoloring (S를 Black, P를 Red)
(S, B)
/ \
(P, R) (C2,B)
/ \
(X,DB)(C1,B) ← 새로운 Sibling!
(S, B)
/ \
(P, R) (C2,B)
/ \
(X,DB)(C1,B) ← 이제 C1이 Black Sibling → Case 2,3,4로 계속
결과: 1번 회전 + Recoloring, Black Sibling 만들기 → 다른 케이스로 이동
이 케이스는 Parent의 색깔에 따라 두 가지로 나뉩니다.
...
|
(P, R) ← Parent가 Red
/ \
(X,DB) (S,B) ← Sibling이 Black
/ \
(B) (B) ← Sibling의 자식들이 모두 Black
/ \ / \
N N N N
Step 1: S를 Red로 변경
...
|
(P, R)
/ \
(X, B) (S, R) ← Sibling을 Red로
/ \
(B) (B)
/ \ / \
N N N N
Step 2: P를 Black으로
...
|
(P, B) ← 완료!
/ \
(X, B) (S, R)
/ \
(B) (B)
/ \ / \
N N N N
...
|
(P, B)
/ \
(X, B) (S, R)
/ \
(B) (B)
/ \ / \
N N N N
결과: Recoloring만, 완료
... ← P 위에 다른 노드 존재
|
(P, B) ← Parent가 Black
/ \
(X,DB) (S,B) ← Sibling이 Black
/ \
(B) (B) ← Sibling의 자식들이 모두 Black
/ \ / \
N N N N
Step 1: S를 Red로 변경하고, P를 Doubly Black으로 간주
...
|
(P, DB) ← P를 새로운 문제 노드로 봄
/ \
(X, B) (S, R) ← S를 Red로 바꿈
/ \
(B) (B)
/ \ / \
N N N N
...
|
(P, DB) ← P를 X로 보고 위로 올라가서 다시 해결
/ \
(X, B) (S, R)
/ \
(B) (B)
/ \ / \
N N N N
결과: S를 Red로 바꾸고, P를 Double Black으로 간주.
P를 새로운 X로 보고 위로 전파 ⬆️ (계속)
(P, ?)
/ \
(X, DB) (S, B)
/ \
(C1,R) (C2,B) ← Near Child만 Red!
/ \ / \
N N N N
Step 1: S를 기준으로 Right Rotation
(P, ?)
/ \
(X, DB) (C1,R)
\
(S,B)
\
(C2,B)
/ \
N N
Step 2: Recoloring (C1을 Black, S를 Red)
(P, ?)
/ \
(X, DB) (C1,B) ← Case 4로 변환!
\
(S,R)
\
(C2,B)
/ \
N N
(P, ?)
/ \
(X, DB) (C1,B)
\
(S,R) ← 이제 Far Child가 Red → Case 4로!
\
(C2,B)
/ \
N N
결과: 1번 회전 + Recoloring, Case 4로 변환
(P, ?) ← P는 Red 또는 Black
/ \
(X, DB) (S, B)
/ \
(C1,?) (C2,R) ← Far Child가 Red!
/ \ / \
N N N N
Step 1: P를 기준으로 Left Rotation
(S, ?)
/ \
(P, ?) (C2,R)
/ \ / \
(X,DB)(C1,?) N N
/ \
N N
Step 2: Recoloring
(S, P의 색) ← S가 P의 원래 색 가져감
/ \
(P, B) (C2,B)
/ \ / \
(X,B)(C1,?) N N
/ \ / \
N N N N
(S, P의 원래 색)
/ \
(P, B) (C2,B)
/ \ / \
(X,B)(C1,?) N N
/ \ / \
N N N N
결과: 1번 회전 + Recoloring, Double Black 해결
| Case | Sibling | 자식 상태 | Parent 색 | Rotation | 결과 | 종료 |
|---|---|---|---|---|---|---|
| 1 | Red | - | - | Left/Right 1회 | Black Sibling 생성 | ❌ 계속 |
| 2.1 | Black | 모두 Black | Red | 없음 | Recolor만 | ✅ 완료 |
| 2.2 | Black | 모두 Black | Black | 없음 | 위로 전파 | ❌ 계속 |
| 3 | Black | Near=Red | - | Right/Left 1회 | Case 4로 변환 | ❌ 계속 |
| 4 | Black | Far=Red | - | Left/Right 1회 | DB 해결 | ✅ 완료 |
핵심 패턴: