Krafton Jungle/3. TIL
[WEEK06] RB트리의 삽입/삭제에 대해 우리집 강아지 문식이도 알기 쉽게 설명해줘
munsik22
2025. 4. 19. 17:48

🐶 좋아, 문식이도 이해할 수 있게 레드 블랙 트리의 삽입과 삭제에 대해 아주 쉽게 설명해볼게!
🟥⬛ RB트리란?
Red-Black Tree는 스스로 균형을 잡는 이진 탐색 트리야. 트리가 너무 한쪽으로 쏠리면 탐색이 느려지니까, 빨간색(Red)과 검정색(Black)을 이용해 규칙을 정해 균형을 맞추는 트리야.
🌱 문식이도 아는 RB트리 규칙
- 각 노드는 빨간색이거나 검정색이다.
- 루트 노드는 항상 검정색이다.
- 모든 리프(nil)는 검정색이다.
- 빨간색 노드의 자식은 반드시 검정색이다. (빨간색끼리 나란히 X)
- 어떤 노드에서 리프까지 가는 모든 경로에는 같은 수의 검정 노드가 있다.
🐶 “루트는 까맣고, 빨강이는 까만 애 옆에만 있어야 하고, 길 따라 검은 애 숫자는 같아야 돼!”
🌱 삽입할 때 어떻게 해?
문식아, 새 친구(노드)를 집에 초대한다고 생각해보자. 근데 이 집은 규칙이 엄~청 엄격해!
- 먼저 새 친구는 빨간색으로 온다!
- 자리에 앉혔는데 규칙을 어기면, 다음 3가지 중 하나를 해줘야 해:
🎨 [Case1] 삼촌이 빨간색일 때 (삼촌 = 부모의 형제)
- 나도 빨강, 아빠도 빨강이면 혼나!
👉 아빠랑 삼촌을 검정으로, 할아버지를 빨강으로 바꿔.
👉 그 다음 할아버지부터 다시 검사해~
🔁 [Case2/3] 삼촌이 검정인데 꼬여있을 때
- 꼬여 있으면 회전(rotate)해서 모양을 반듯하게 만든다!
- 회전 후 색을 바꿔서 규칙을 다시 맞춰~
🐶 “새 친구는 빨간 옷 입고 와! 근데 빨강이 둘이 붙어 있으면 혼나니까, 돌리거나 색깔 바꾸는 거야!”
RB_INSERT(tree, new_node):
1. new_node를 BST 방식으로 삽입한다
2. new_node의 색을 RED로 설정한다
3. while new_node의 부모가 RED일 때:
4. 부모가 할아버지의 왼쪽 자식이면:
삼촌 = 할아버지의 오른쪽 자식
if 삼촌이 RED이면: # Case 1
부모와 삼촌을 BLACK으로
할아버지를 RED로
new_node = 할아버지로 올려보내
else:
if new_node가 부모의 오른쪽 자식이면: # Case 2
new_node = 부모로 올리고
왼쪽으로 회전(new_node)
# Case 3
부모를 BLACK, 할아버지를 RED로
오른쪽으로 회전(할아버지)
(오른쪽 자식인 경우는 위 과정을 좌우 반대로)
5. 루트는 항상 BLACK으로 만든다
🌱 삭제할 때는 어떻게 해?
문식아, 친구 하나가 집에서 나가게 됐어. 근데 검정색 친구가 나가면 균형이 깨질 수 있어. 그럼 나머지 애들이 불편해하겠지?
- 검정색 친구가 나가면, 그 빈자리에 ‘추가 검정색’을 붙여서 문제 해결을 시작해.
- 이 ‘이중 검정색’을 없애려면 4가지 상황을 봐야 해:
🔥 [Case1] 형이 빨강이다
- 형을 검정으로, 부모를 빨강으로 바꾼 뒤 회전!
👉 그럼 문제는 다른 케이스로 바뀌고 다시 검사~
🧤 [Case2] 형이 검정이고, 형의 자식들도 검정
- 형을 빨강으로 칠해!
👉 부모에게 이중검정이 생기므로 다시 위로 올라가~
🔄 [Case3/4] 형의 자식 중 하나가 빨강
- 형을 부모의 색으로 바꾸고, 부모는 검정, 형의 빨간 자식은 검정으로
👉 그리고 회전하면 OK!
🐶 “검정 친구가 나가면 색깔 맞추는 놀이 시작! 형이 빨강인지, 검정인지 보고 돌리고, 색칠하고… 결국 다 균형 맞추는 거야!”
RB_DELETE(tree, node_to_delete):
1. node_to_delete를 BST 방식으로 삭제한다
→ 삭제 후 자리에 y가 남고, y의 원래 색이 중요함
2. 만약 y의 원래 색이 BLACK이라면:
→ 균형이 깨졌으므로 fixup 시작!
RB_DELETE_FIXUP(tree, x) # x는 삭제 후 올라온 자식
RB_DELETE_FIXUP(tree, x):
while x ≠ root and x의 색이 BLACK:
if x는 부모의 왼쪽 자식이면:
w = x의 형
if w의 색이 RED: # Case 1
w를 BLACK, 부모를 RED로
왼쪽으로 회전(부모)
w = x의 새 형
if w의 두 자식이 모두 BLACK이면: # Case 2
w를 RED로
x = 부모로 올려보내
else:
if w의 오른쪽 자식이 BLACK이면: # Case 3
w의 왼쪽 자식 = BLACK
w = RED
오른쪽으로 회전(w)
w = x의 새 형
# Case 4
w의 색 = 부모의 색
부모와 w의 오른쪽 자식 = BLACK
왼쪽으로 회전(부모)
x = root로 설정
(오른쪽 자식인 경우는 좌우 반대로)
x = BLACK으로 설정
📝 정리
| 상황 | 설명 |
| 삽입 | “새 친구는 빨강으로 오고, 규칙 어기면 회전하거나 색 바꿔!” |
| 삭제 | “검정 친구 나가면, 남은 애들끼리 균형 맞추려고 회전하고 색칠해!” |
삽입 Case별 정리
| Case | 조건 | 처리 방식 | 효과 |
| Case 1 | 부모( 🟥 ), 삼촌( 🟥 ) | 부모와 삼촌 → ⬛ 할아버지 → 🟥 할아버지를 기준으로 다시 검사 |
색상 조정만으로 해결 가능, 위로 전파됨 |
| Case 2 | 부모( 🟥 ), 삼촌( ⬛ ) 내가 삼촌 쪽 방향 자식 (inward) |
부모를 기준으로 회전 (내가 부모와 일직선 되게) |
Case 3로 바꾸기 위한 중간 단계 |
| Case 3 | 부모( 🟥 ), 삼촌(BLACK) 내가 부모와 일직선 (aligned) |
부모 → ⬛ , 할아버지 → 🟥 할아버지 기준 회전 |
색 조정 + 회전으로 문제 해결 |
삭제 Case별 정리
| Case | 조건 | 처리 방식 | 효과 |
| Case 1 | x의 형제(w)가 🟥 | w → ⬛, 부모 → 🟥 부모 기준 회전 w를 새 형제로 갱신 |
형을 ⬛ 으로 만들어 다음 Case로 이동 가능하게 함 |
| Case 2 | w는 ⬛ w의 자식 둘 다 ⬛ |
w → 🟥 x = 부모로 올림 (이중 검정 위로 전달) |
색만 바꿔주고 문제를 부모에게 위임함 |
| Case 3 | w는 ⬛ w의 왼쪽 자식 🟥 w의 오른쪽 자식 ⬛ |
w → 🟥 w의 왼쪽 자식 → ⬛ w 기준으로 오른쪽 회전 |
Case 4로 바꾸기 위한 중간 단계 |
| Case 4 | w는 ⬛ w의 오른쪽 자식 🟥 |
w의 색 → 부모의 색 부모, w의 오른쪽 자식 → ⬛ 부모 기준 왼쪽 회전 |
최종 회전으로 이중 검정 해소, 종료 |