이진 탐색 트리의 공간 복잡도는 이며 탐색, 삽입, 삭제 연산에 대한 최악의 경우 시간 복잡도는 이다. 평균적인 경우의 시간 복잡도는 모든 연산에 대해 이다.
이진 탐색 트리는 훌륭한 탐색 알고리즘이지만, 노드를 삽입하고 삭제하다보면 트리가 한쪽으로 쏠린 모양이 되기 쉽다는 단점이 있다. 예를 들어 10, 9, 8, 7, 6의 순서로 삽입하여 이진 탐색 트리를 만들면 위와 같은 모양의 이진 트리가 되는데 이렇게 한 쪽으로 치우친 이진 트리를 경사 이진 트리라고 한다.
이진 탐색 트리가 이렇게 경사 이진 트리같은 모양이 될수록 탐색의 시간 복잡도가 이진 탐색이 아닌 순차 탐색에 가까워지기 때문에 탐색의 효율성이 저하된다.
이러한 문제를 해결하려면 트리에 노드를 삽입하거나 삭제할 때 마다 높이를 낮게 유지하여 균형을 잡는 자가 균형(self-balancing) 이진 탐색 트리가 필요하다. 이러한 트리로는 AVL 트리, 레드-블랙 트리 등이 있다.
자가 균형 트리 외에 다른 방법으로는 자주 탐색되는 노드를 트리의 뿌리 노드에 가깝게 재배치하는 방법이 있다. 이러한 트리로 스플레이(Splay) 트리가 있다.
레드-블랙 트리는 자가 균형 이진 탐색 트리의 일종으로, 모든 노드를 레드 또는 블랙으로 표시하여 트리의 균형을 유지하기 때문에 레드-블랙 트리라고 부른다.
레드-블랙 트리의 공간 복잡도는 이며, 모든 상황에서 탐색, 삽입, 삭제의 시간 복잡도가 으로 동일하다.
레드-블랙 트리는 구현이 복잡하지만 매우 효율적인 알고리즘이기 때문에 다양하게 활용된다.
각종 프로그래밍 언어의 연관 배열 자료형(파이썬의 딕셔너리, C++의 map이나 set 등)들은 대부분 레드-블랙 트리 기반으로 구현되어 있다.
레드-블랙 트리는 2-3-4 트리와 매우 유사하며 등거리 변환(isometry)이 가능하다. 즉, 모든 2-3-4 트리에는 구성 원소와 그 순서가 같은 레드-블랙 트리가 최소한 하나 이상 존재한다는 뜻이다.
레드-블랙 트리는 다음과 같은 규칙을 이용하여 균형을 유지한다.
레드-블랙 트리의 규칙을 지키기 위해서, 모든 잎 노드는 아무 데이터도 갖지 않으면서 블랙인 NIL 노드가 된다. 이러한 노드를 센티넬(sentinel) 노드라고 부른다.
NIL 노드는 구현의 편의를 위해 이용되는 노드이므로 보통 메모리를 할당하지 않는다.
레드-블랙 트리의 탐색 과정은 이진 탐색 트리의 탐색 방법과 동일하다.
레드-블랙 트리에서 노드를 삽입하거나 삭제하면 균형이 깨질 수 있기 때문에 노드의 색을 바꾸거나 노드를 회전하는 과정이 필요하다. 회전은 방향에 따라 좌회전과 우회전으로 구분된다.
좌회전은 오른쪽 자식 노드의 왼쪽 자식 노드를 부모 노드의 오른쪽 자식으로 연결한다. 우회전은 그 반대로 왼쪽 자식 노드의 오른쪽 자식 노드를 부모 노드의 왼쪽 자식으로 연결한다.
레드-블랙 트리에 노드를 삽입하는 과정은 다음과 같다.
삽입할 노드를 초기화 한다. 노드의 색은 레드로 하고 양쪽 자식으로 NIL을 연결하면 된다.
레드-블랙 트리를 이진 탐색하여 삽입할 노드가 연결될 위치를 찾는다. 트리가 빈 상태라면 삽입할 노드는 루트 노드가 된다. 삽입할 노드의 부모 노드가 있다면 그 부모 노드의 NIL 노드를 떼어내고 그 자리에 연결한다.
삽입할 노드의 부모 노드가 블랙이면 규칙을 위반할 일이 없으므로 그대로 둔다.
삽입할 노드의 부모 노드가 레드이면, 삼촌 노드(부모 노드의 형제 노드)의 색에 따라 다른 과정을 거쳐야 한다.
a. 삼촌이 레드인 경우: 삽입할 노드의 부모 노드와 삼촌 노드를 모두 블랙으로 만들고 할아버지 노드를 레드로 만든다. 할아버지 노드가 3번 규칙을 위반하는 상태가 되면 할아버지 노드를 새로 삽입한 노드로 간주하고 다시 처음부터 세 가지 경우를 따져봐야 한다.
b. 삼촌이 블랙이며 삽입할 노드가 부모 노드의 오른쪽 자식인 경우: 삽입할 노드의 부모 노드를 기준으로 좌회전 시킨다. 이렇게 하면 밑에서 설명한 c의 상황이 되므로 같은 방법으로 처리하면 된다.
c. 삼촌이 블랙이며 삽입할 노드가 부모 노드의 왼쪽 자식인 경우: 삽입할 노드의 부모 노드를 블랙으로 만들고 할아버지 노드를 레드로 만든 다음 할아버지 노드를 우회전 시킨다. 이렇게 하면 3번 규칙을 위반할 일이 없어진다.
위 과정의 결과로 뿌리 노드가 레드가 되면 연산의 마지막 단계에서 블랙으로 바꿔준다.
레드-블랙 트리에 노드를 삭제하려면, 삭제할 노드의 색에 따라 다른 과정을 거쳐야 한다.
삭제할 노드가 레드인 경우 규칙을 위반할 위험이 없으므로 기본적으로 이진 탐색 트리의 삭제 연산과 동일하며, 이 과정에서 노드의 색깔만 적절히 바꿔주면 된다.
삭제할 노드가 블랙인 경우 3, 4번 규칙을 위반할 위험이 생긴다. 규칙을 지키려면 삭제된 노드를 대체하는 노드(successor)를 블랙으로 바꿔야 한다. 대체할 노드가 레드였다면 더 이상의 문제가 없지만, 블랙이었다면 이 노드는 이중 흑색 노드가 되어 1번 규칙을 위반하게 되므로 이를 해결해야 한다.
이중 흑색 노드를 처리하는 방법은 이중 흑색 노드의 형제와 조카 노드들의 색에 따라 다음 네 가지 경우로 나뉜다.
형제가 레드인 경우: 형제는 블랙, 부모는 레드로 만들고, 부모를 기준으로 자식 노드를 좌회전시킨다. 그 후에는 2번의 a, b, c 중에서 일치하는 경우에 따라 처리하면 된다.
형제가 블랙인 경우는 다음의 세 가지로 나뉜다.
a. 형제의 양쪽 자식이 모두 블랙인 경우: 형제만 레드로 만들고 이중 흑색 노드가 갖고 있던 2개의 블랙 중 하나를 부모 노드에게 넘겨준다. 그 후에는 부모 노드를 기준으로 네 가지 경우 중 어떤 경우에 해당 되는 지를 따져서 그에 맞게 처리한다.
b. 형제의 왼쪽 자식은 레드, 오른쪽 자식은 블랙인 경우: 형제는 레드로, 형제의 왼쪽 자식은 블랙으로 만든다. 그 후에 형제 노드를 기준으로 우회전한다. 이렇게 하면 c의 상황과 같아지므로 c의 처리 방법을 따르면 된다.
c. 형제의 오른쪽 자식이 레드인 경우: 이중 흑색 노드의 부모 노드가 갖고 있는 색을 형제 노드에 칠한다. 그 다음에 부모 노드와 형제 노드의 오른쪽 자식 노드를 블랙으로 만들고, 부모 노드를 기준으로 좌회전 한다. 마지막으로 이중 흑색 노드를 블랙으로 만든다.