자가 균형 이진 탐색 트리
아래의 조건을 만족한다.
[black depth]
[높이]
n개의 노드들이 있는 red-black tree에서의 높이는 O(logn)이다.
→ 정확히 왼쪽, 오른쪽으로 개수가 n/2씩으로 반반 나뉘어지지는 않지만, balanced이므로 O(logn)로 bound된다는 사실만 알자.
-> Search, Insert, Delete에 대한 시간복잡도 또한 O(logN)
레드-블랙 트리에 새로운 노드를 삽입할 때 새로운 노드는 항상 빨간색으로 삽입한다.
이렇게 되면 'No Double Red' 조건이 위배되는 상황이 발생한다. 즉, 빨간색 노드가 연속으로 2번 나타날 수 있다(Double Red)
레드 블랙 트리는 이러한 Double Red 문제를 해결하기 위해 2가지 전략을 사용한다.
(앞으로 새로 삽입할 노드를 N(New), 부모 노드를 P(Parent), 조상 노드를 G(Grand Parent), 삼촌 노드를 U(Uncle)라고 하자. 즉, 삼촌 노드 : 부모의 형제)
Double Red가 발생했을 때
Restructuring 과정
먼저 새로운 노드 N과 부모 P, 조상 G를 오름차순으로 정렬한다. 그러면 3이 중간값이 된다.
중간값인 3을 부모 노드로 바꾸고 나머지 2와 5를 자식 노드로 바꾼다.
당연히 원래 5의 자식 노드였던 7은 딸려가게 된다.
마지막으로 새롭게 부모가 된 3을 검은색으로 바꿔주고 나머지 두 자식인 2, 5의 색을 빨간색으로 바꿔주면 Double Red 문제가 해결된다!
여기서 많이들 헷갈리는 게 완성된 트리가 '모든 리프 노드는 검은색' 규칙을 만족하지 않는 것처럼 보일 수 있다.
이는 값이 2인 노드는 자식 노드 NIL 2개를 가지고 있고 그 NIL들이 검은색이라고 생각하면 된다.
Recoloring 과정
Double Red가 발생했는데 삼촌 노드가 빨간색이다. 따라서 Recoloring을 수행한다.
먼저 부모(P)와 삼촌(U)을 검은색으로 바꾸고, 조상(G)을 빨간색으로 바꾼다.
하지만 루트 노드는 검은색이라는 조건을 지켜야 하므로, 루트 노드를 검은색으로 바꾼다.
이렇게 하면 모든 조건이 지켜지면서 Double Red 문제가 해결된다.
검은색 노드는 2번 나와도 되냐고 묻는다면 Yes이다.
빨간색 노드가 2번 나오면 안 되는 것이다.
Recoloring은 간단해 보이지만 문제는 조상 노드(G)가 루트 노드가 아니면서, 조상 노드(G)가 또다시 Double Red 문제가 발생하는 경우이다.
이 경우를 살펴보자.
위와 같은 상황을 가정하자. 왼쪽 트리에서 Recoloring을 진행하면 오른쪽 트리가 된다.
이때 조상 노드(G)가 또다시 Double Red가 발생하게 된다.
Double Red 문제가 발생한 "값이 5인 노드"를 기준으로 다시 한번 살펴보자.
해당 노드의 삼촌(U)이 빨간색이므로 다시 Recoloring을 진행해주면 Double Red 문제를 해결할 수 있다!
만약 해당 노드의 삼촌(U)가 검은색이었다면 Restructuring을 진행해주면 된다.
레드-블랙 트리에 순서대로 8, 7, 9, 3, 6, 4, 5, 12를 삽입한 후의 상태를 그리시오.
"삼촌 노드가 없는데??"라고 생각할 수 있다.
맨 위의 [그림 1]을 보면 모든 리프 노드들은 검은색 NIL 노드인 것을 확인할 수 있다.
즉, 좀 비어있는 것처럼 보이면 그냥 검은색 노드가 있다고 생각하면 편하다.
따라서 Restructuring을 진행하면 된다.
눈으로 직접 확인해보고 싶다면 아래 사이트를 참고하자.
레드 블랙 트리에 원소를 삽입하는 과정을 확인할 수 있다.
https://www.cs.usfca.edu/~galles/visualization/RedBlack.html