레드블랙트리(Red Black Tree)는 자기 균형 이진 탐색 트리 구조로, 삽입과 삭제 연산 이후 레드/블랙의 색상을 사용하여 균형잡힌 정렬을 하는 이진 탐색 트리(BST)입니다.
속성
- 모든 노드는 빨간색 또는 검은색을 가지고 있다.
- 루트 노드는 항상 검은색 이다.
- Leaf(NIL) 노드는 항상 검은색 이다.
- 빨강 노드의 자식은 모드 검정색이다.
- 임의의 노드에서 모든 리프노드에 이르는 경로에는 동일한 수의 검정 노드가 필요하다.
※NIL : 아무 데이터도 가지고 있지않는 더미 노드.
특징
- 이진 탐색 트리(BST)의 한 종류
- BST의 최악의 경우 O(N)의 시간 복잡도를 개선해서 모든 경우의 시간복잡도 O(log N)을 유지
- 항상 균형을 유지하여 특정 케이스에 치우친 성능 저하가 없다.
- 삽입,삭제 시 회전 연산을 통해 균형을 유지한다.
- Map, Set 자료구조는 RBT를 기반으로 구현되었다.
회전연산
삽입,삭제,탐색시 시간복잡도가 항상 O(log N)을 유지하기위해서 항상 균형잡힌 상태를 유지합니다.
해당 과정에서는 RBT의 속성을 유지하며 트리 구조를 조정하는데에는 왼쪽회전, 오른쪽 회전의 방식이 있습니다.
삽입
- 새 노드는 처음에 빨간색으로 삽입된다.
- 삽입 후, 트리는 RB-T 속성을 위반할 수 있으므로, 이를 수정하기 위해 재조정 및 색상 변경이 수행된다.
- 삽입된 노드의 부모가 검정이면 트리 속성이 유지되므로 조정하지 않는다.
- 삽입된 노드의 부모와 삼촌이 둘다 빨강일 경우
- 부모 삼촌은 검정으로 변경
- 조부모를 빨강으로 변경
- 재귀적 처리를 통해 색상 조정
- 부모가 빨강이고 삼촌이 검정일 경우
- 회전연산을 통해 색상이 조정된다.
- 노드들은 필요에 따라 색상이 변경될 수 있으며, 회전연산을 통해 균형을 유지한다.
- BST와같이 재귀적으로 노드를 호출하며 조정된다.
삭제
- 삭제 노드가 레드 노드일 경우
- 삭제 후 조정 처리가 필요없다
- 삭제 노드가 블랙 노드인 경우
- 삭제 노드의 자리가 RBT속성을 위반하므로 추가적인 작업을 수행한다.
- 형제가 레드일 경우
- 부모-형제 색상 교환
- 부모를 기준으로 회전연산
- 형제가 블랙, 형제의 자식이 모두 블랙
- 형제를 레드로 변경
- 부모노드를 검정으로 변경 후 형제가 레드일 경우의 단계를 처러리
- 형제가 블랙, 형제의 자식중 하나가 레드
- 형제와 형제의 자식(레드)의 색상을 교환
- 자식(레드)가 왼쪽일 경우 형제노드를 기준으로 오른쪽 회전
- ---- 형제의 자식(레드)가 오른쪽일 경우 다음 단계부터 수행 ----
- 부모와 형제 노드의 색상을 교환
- 부모를 기준으로 왼쪽 회전
- 형제노드의 오른쪽 자식을 블랙으로 변경
회전연산 - 왼쪽 회전
// Left Rotation
void leftRotate(Node* node) {
Node* rightNode = node->right; // 노드의 오른쪽 자식을 가져옴
if (rightNode == nullptr) return; // 오른쪽 자식이 없으면 회전 불가
node->right = rightNode->left; // 노드자식(오른쪽)의 왼쪽 서브트리를 노드의 오른쪽에 연결
if (rightNode->left != nullptr) {
rightNode->left->parent = node;
}
rightNode->parent = node->parent; // 노드의 부모를 노드자식(오른쪽)의 부모로 설정
if (node->parent == nullptr) {
root = rightNode; // 노드가 루트라면 노드자식(오른쪽)가 새 루트가 됨
}
else if (node == node->parent->left) {
node->parent->left = rightNode;
}
else {
node->parent->right = rightNode;
}
rightNode->left = node; // 노드를 노드자식(오른쪽)의 왼쪽 자식으로 설정
node->parent = rightNode;
}
회전연산 - 오른쪽 회전
//Right Rotation
void rightRotate(Node* node) {
Node* leftNode = node->left; // 노드의 왼쪽 자식을 가져옴
if (leftNode == nullptr) return; // 왼쪽 자식이 없으면 회전 불가
node->left = leftNode->right; // 노드 자식(왼쪽)의 오른쪽 서브트리를 노드의 왼쪽에 연결
if (leftNode->right != nullptr) {
leftNode->right->parent = node;
}
leftNode->parent = node->parent; // 노드의 부모를 노드 자식(왼쪽)의 부모로 설정
if (node->parent == nullptr) {
root = leftNode; // 노드가 루트라면 노드 자식(왼쪽)가 새 루트가 됨
}
else if (node == node->parent->left) {
node->parent->left = leftNode;
}
else {
node->parent->right = leftNode;
}
leftNode->right = node; // 노드를 노드 자식(왼쪽)의 오른쪽 자식으로 설정
node->parent = leftNode;
}
'알고리즘 , 자료구조' 카테고리의 다른 글
[알고리즘] 해시 테이블 (Hash Table) (0) | 2025.01.16 |
---|---|
[알고리즘] 힙 / 병합 정렬 (Heap / Merge Sort) (0) | 2025.01.14 |
[알고리즘] 이진탐색트리 BST(Binary Search Tree) (0) | 2025.01.09 |
[자료구조] 트리 (Tree) (0) | 2025.01.08 |
[자료구조] 그래프 (Graph) (0) | 2025.01.07 |