Red Black Tree
1. Concept [revisited]
๋ค์๊ณผ ๊ฐ์ ์ฑ์ง์ ๋ง์กฑํ๋ ์ด์ง ๊ฒ์ ํธ๋ฆฌ BST
- ๋ชจ๋ ๋ ธ๋๋ red or black
- root ๋ ธ๋๋ black
- leaf (nil)๋ ธ๋๋ black
- red ๋ ธ๋์ ์์์ black
- ํ ๋ ธ๋์์ leaf(nil)๋ก ๊ฐ๋ ๊ฐ ๊ฒฝ๋ก์ ํฌํจ๋ black ๋ ธ๋์ ๊ฐ์๋ ๋ชจ๋ ๊ฐ๋ค.
2. Operations
typedef enum {RBTREE_BLACK, RBTREE_RED} color_t;
typedef int key_t;
typedef struct node_t {
key_t key;
color_t color;
struct node_t* parent;
struct node_t* left;
struct node_t* right;
}
typedef struct rbtree {
node_t* root;
node_t* nil;
}
์์ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ํ์. ๋ค์๊ณผ ๊ฐ์ ์ฐ์ฐ์ด red black ํธ๋ฆฌ์ ๊ธฐ๋ณธ ์ฐ์ฐ์ด๋ค.
rbtree* new_rbtree();
void free_rbtree(rbtree*);
node_t* rbtree_insert(rbtree*, key_t);
int* rbtree_delete(rbtree*, node_t*);
node_t* rbtree_find(const rbtree*, key_t);
node_t* rbtree_min(const rbtree*);
node_t* rbtree_max(const rbtree*);
int rbtree_to_array(rbtree*, key_t*, int);
- new_rbtree: ํธ๋ฆฌ์ ์์ฑ
- free_rbtree: ํธ๋ฆฌ์ ์ญ์ (๋ฉ๋ชจ๋ฆฌ ํด์ )
- rbtree_insert: ํธ๋ฆฌ์ ์๋ก์ด ๋ ธ๋ ์ฝ์
- rbtree_delete: ํธ๋ฆฌ์ ์๋ ๋ ธ๋ ์ญ์
- rbtree_find: ํธ๋ฆฌ์์ ํค ๊ฐ์ ๊ฐ๋ ๋ ธ๋ ๊ฒ์
- rbtree_min/rbtree_max: ํธ๋ฆฌ์ ์ต์/์ต๋๊ฐ ๋ฐํ
- rbtree_to_array: ํธ๋ฆฌ๋ฅผ ํค ๊ฐ ์ค๋ฆ์ฐจ์์ผ๋ก ๋ฐฐ์ด์ ๋ด์ ๋ฐํ
์ด์ค์์ find, min/max, array ์ฐ์ฐ์ read-only ์ฐ์ฐ์ผ๋ก, ์ผ๋ฐ ์ด์ง๊ฒ์ํธ๋ฆฌ์ ๋์ผํ๊ฒ ์ฒ๋ฆฌํด์ค ์ ์๋ค. ํธ๋ฆฌ์ ์์ฑ๊ณผ ์ญ์ ์ญ์ ๋ง์ฐฌ๊ฐ์ง๋ค. ์ค์ํ ๋ถ๋ถ์ ๋ ธ๋์ ์ฝ์ /์ญ์ ์ฐ์ฐ์ธ๋ฐ, ์ด๋ ํธ๋ฆฌ์ ๋ณํ๋ฅผ ๊ฐํ๋ ์ฐ์ฐ์ผ๋ก์ ์ฐ์ฐ ํ์๋ red black ์ฑ์ง์ ๋ง์กฑํ ์ ์๋๋ก ๋ณด์ฅํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
3. Insertion ์ฝ์
1. Basic Idea
- ์ผ๋ฐ ์ด์ง ํ์ ํธ๋ฆฌ์ ๊ฐ์ด ๋ ธ๋๋ฅผ ์ฝ์ ํ ๊ณณ์ ์ฐพ๋๋ค.
- ์ฝ์ ํ ๋ ธ๋๊ฐ red black ์์ฑ์ ์๋ฐํ๋์ง ๊ฒ์ฌํ๋ค.
- ์๋ฐํ ๊ฒฝ์ฐ, ์์ฑ์ ๋ณต๊ตฌํ๋ค.
2. Rule Violation
์๋ก์ด ๋ ธ๋์ ์์ red๋ก ์ค์ ํ๊ณ ์ฝ์ ์ํค๋ฏ๋ก, ๋ ๊ฐ์ง ์์ฑ์ด ์๋ฐ๋ ์ ์๋ค.
- Rule 2: ๋ฃจํธ๋ฅผ ์ฝ์ ํ๋ค๋ฉด, ๋ฃจํธ๊ฐ black์ด์ด์ผ ํ๋ค๋ ์์ฑ์ ์๋ฐํ๋ค.
- Rule 4: red์ธ ๋ ธ๋์ ์์์ผ๋ก ์๋ก์ด ๋ ธ๋๋ฅผ ์ฝ์ ํ ์ ์๋ค.
์ด ๋ ๊ฐ์ง ์๋ฐ์ ๋์์ ์ผ์ด๋์ง ์๋๋ค ์ฆ 2๊ฐ ์๋ฐ๋๋ฉด 4๋ ์ง์ผ์ง๋๋ฐ, ์ด๋ 2๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ ๋น ํธ๋ฆฌ์ ๋ฃจํธ๊ฐ ์ฝ์ ๋๋ ๊ฒฝ์ฐ๋ฐ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ํ 4๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ, red ๋ ธ๋๋ ๋ฃจํธ๊ฐ ๋ ์ ์๊ณ , ์์ฑ ์๋ฐ์ ์๋ก์ด ๋ ธ๋์ ๊ทธ ๋ถ๋ชจ ์ฌ์ด์์๋ง ์ผ์ด๋๋ฏ๋ก ๋ฃจํธ๊ฐ black์ด์ด์ผ ํ๋ค๋ 2๋ฒ ๊ท์น์ ์ง์ผ์ง๊ฒ ๋๋ค.
๋ง์ฝ ์ฝ์ ํ ๋ ธ๋ z์ ๋ถ๋ชจ๊ฐ black ๋ ธ๋๋ผ๋ฉด, ์์ฑ์ ์๋ฐํ์ง ์๋๋ค. ์ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ฌ๋ ์ฝ์ ํ ๋ ธ๋ z์ ๋ถ๋ชจ๊ฐ red๋ผ๋ฉด, fixup ์ฐ์ฐ์ ํตํด ์ ๋ ๊ฐ์ง ์๋ฐ์ ๊ฒ์ฌํ๊ณ ์์ ํด์ผ ํ๋ค. fixup์ ์ผ์ด์ค๋ ์ด 6๊ฐ๋ก, 1-3์ผ์ด์ค๋ 4-6์ผ์ด์ค์ ๋์นญ์ด๋ค.
rbtree_insert_fixup(t, z)
while z.parent.color == RED
if z.parent == z.parent.parent.left
u = z.parent.parent.right // uncle
if u.color == RED // case 1
z.parent.color = BLACK
u.color = BLACK
z.parent.parent.color = RED
z = z.parent.paret
else if z = z.parent.right // case 2
z = z.parent
rotate_left(t, z)
z.parent.color = BLACK // case 3
z.parent.parent.color = RED
rotate_right(t, z.parent.parent)
else
if z.parent == z.parent.parent.right
u = z.parent.parent.left // uncle
if u.color == RED // case 4
z.parent.color = BLACK
u.color = BLACK
z.parent.parent.color = RED
z = z.parent.parent
else if z = z.parent.left // case 5
z = z.parent
rotate_right(t, z)
z.parent.color = BLACK // case 6
z.parent.parent.color = RED
rotate_left(t, z.parent.parent)
t.root.color = BLACK
๐ while ๋ฃจํ ์์์ z.parent.parent
๊ฐ ํญ์ ์กด์ฌํ๋ ์ด์ ๋? while ๋ฃจํ๋ก ์ง์
ํจ๊ณผ ๋์์ z
์ z.parent
์ ์์ RED์์ด ๋ณด์ฅ๋๋ค. ์ฝ์
์ฐ์ฐ ์ด์ ์ ํธ๋ฆฌ๋ red black์ ์ฑ์ง์ ๋ง์กฑํ๋ฏ๋ก z.parent.parent
๋ black์ด๊ณ , ํญ์ ์กด์ฌํ๋ค. (red์ธ z.parent
๊ฐ root๊ฐ ๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.)
๋์นญ์ธ 1-3๋ง ๋ณด์ธ๋ค. ๋จผ์ ์ผ์ด ๋
ธ๋๋ฅผ ์ ์ํ๋ค.u = x.parent.parent.right
(x.parent.parent.left = x.parent
์ธ ๊ฒฝ์ฐ)
CASE 1: u๊ฐ red์ธ ๊ฒฝ์ฐ

- z.parent.color = BLACK
- u.color = BLACK
- z.parent.parent.color = RED
- z = z.parent.parent
CASE1์์๋ red parent - red child์ธ ๊ฒฝ์ฐ๋ฅผ ํด์ํ๋ค. ๊ทธ๋ฆฌ๊ณ z = z.parent.parent
๋ฅผ ํตํด 2๋จ๊ณ ์๋ก ์ฌ๋ผ๊ฐ๋ค. ๋ง์ฝ ์ฌ๋ผ๊ฐ z
์ ๋ถ๋ชจ๊ฐ red๋ผ๋ฉด while์ ๋ค์ ์ง์
ํ๊ณ , ์๋ ๊ฒฝ์ฐ ์ข
๋ฃํ๋ค.
CASE 2: u๊ฐ black์ด๊ณ z๊ฐ ๋ถ๋ชจ์ right child์ธ ๊ฒฝ์ฐ

- z = z.parent
- rotate_left(t, z);
CASE2๋ CASE3๋ฅผ ์๋นํ๋ค. z๋ฅผ ํ ๋จ๊ณ ์๋ก ์ฌ๋ ค์ค ํ left๋ก ๋๋ฆฐ๋ค. z
๋ฅผ ํ๋จ๊ณ ์๋ก ์ฌ๋ฆฌ๋ ์ด์ ๋, CASE3 ์ง์
์ ์ํด z
์ z.parent
๊ฐ red์ธ ์ํฉ์ ๋ง๋ค์ด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
CASE 3. u๊ฐ black์ด๊ณ z๊ฐ ๋ถ๋ชจ์ left child์ธ ๊ฒฝ์ฐ

- z.parent.color = BLACK
- z.parent.parent.color = RED
- rotate_right(t, z.parent.parent)
CASE3๋ ์์ ๊ณผ์ ์ ํตํด red parent - red child์ ์๋ฐ์ ํด๊ฒฐํ๋ค.
๐ค root๊ฐ red์ธ ์๋ฐ์ ์ด๋ป๊ฒ ํด์๋ ๊น? z == root
์ธ ๊ฒฝ์ฐ z.parent.color == RED
๋ผ๋ ์กฐ๊ฑด์ ๋ถํฉํ์ง ์์ผ๋ฏ๋ก while๋ฌธ์ ์ง์
ํ์ง ์๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง ๋ผ์ธ์ธ t.root.color = BLACK
์ ํตํด ์๋ฐ์ ํด์ํ๋ค.
4. Deletion ์ญ์
1. Basic Idea
- ์ผ๋ฐ ์ด์ง ํ์ ํธ๋ฆฌ์ ๊ฐ์ด ๋ ธ๋๋ฅผ ์ญ์ ํ๋ค.
- ์ญ์ ๋ ๋ ธ๋๋ฅผ ๋์ฒดํ๋ ๋ ธ๋๊ฐ red black ์์ฑ์ ์๋ฐํ๋์ง ๊ฒ์ฌํ๋ค.
- ์๋ฐํ ๊ฒฝ์ฐ, ์์ฑ์ ๋ณต๊ตฌํ๋ค.
2. Rule Violation
์ญ์ ์ฐ์ฐ์ ์ฝ์ ๋ณด๋ค ์์ฑ์ ์๋ฐํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ ๋ง๋ค. ์๋ฐ๊ฐ๋ฅ์ฑ์ ์ญ์ ๋ ๋ ธ๋์ ์์ ์์กดํ๋ค. ๋ ธ๋๋ฅผ ์ญ์ ํ ๋ ๋ฐ์ํ ์ ์๋ ์์ฑ ์๋ฐ์ ๊ฒํ ํ๊ธฐ ์ํด, ์ญ์ ์ํฉ์์ ์ธ ๊ฐ์ง์ ๊ตฌ๋ถ์ด ํ์ํ๋ค.
์ด๋ฆ | ์ค๋ช |
---|---|
z | ๋ด๊ฐ ์ญ์ ํ๋ ค๋ key๊ฐ์ ๊ฐ์ง ๋ ธ๋ |
y | ํธ๋ฆฌ์์ ์ญ์ ๋๋ ๋ ธ๋ |
x | ์ญ์ ๋ ์๋ฆฌ๋ฅผ ๋์ฒดํ๋ ๋ ธ๋ |
[์ผ๋ฐ ์ด์ง๊ฒ์ํธ๋ฆฌ์ ์ญ์ ์ฐ์ฐ]
- leaf ๋ ธ๋์ผ๋๋ ์ญ์ ํ๋ค.
- ์์์ด ํ๋๋ง ์์ ๋๋ ์์์ ์์ ์ ์์น๋ก ๊ต์ฒดํ๊ณ ์์ ์ ์ญ์ ํ๋ค.
- ์์์ด ๋ ๋ค ์์ ๋๋ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์์ ์ต์๊ฐ์ ์ฐพ์ ์์ ๊ณผ ๊ต์ฒดํ๊ณ ์ต์๊ฐ ๋
ธ๋๋ฅผ ์ญ์ ํ๋ค.
3.1. ์ต์๊ฐ ๋ ธ๋๋ left ์์์ ๊ฐ์ง ์๊ธฐ ๋๋ฌธ์ ํญ์ 1๋ฒ ๋๋ 2๋ฒ ์ผ์ด์ค์ ํด๋นํ๋ค.
3.2. ์์ ์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์์ ์ต๋๊ฐ์ ์ฐพ์ ๊ต์ฒดํด๋ ๋๋ค. ์ด ๊ฒฝ์ฐ์๋ ์ต๋๊ฐ ๋ ธ๋๋ right์์์ ๊ฐ์ง ์๋๋ค.
์ผ๋ฐ ์ด์ง๊ฒ์ํธ๋ฆฌ์์ ๋
ธ๋๋ฅผ ์ญ์ ํ ๋, 1๋ฒ, 2๋ฒ ์ผ์ด์ค์ ํด๋นํ๋ ๊ฒฝ์ฐ z์ y๋ ์๋ก ๊ฐ๋ค. ์ด ๊ฒฝ์ฐ y = z
๋ก ๋ณด๊ณ , x = y.child
๋ก ์ค์ ํด ์ค๋ค. ๊ทธ๋ฌ๋ 3๋ฒ ์ผ์ด์ค์์๋ z์ y๋ฅผ ๊ตฌ๋ถํด์ผ ํ๋ค. z์ ์์น์ y = ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ์ต์๊ฐ
์ด ์ฎ๊ฒจ์ง๊ณ , ๊ฒฐ๊ตญ ์ญ์ ๋๋ ๊ฒ์ y์ด๋ฏ๋ก y์ ์๋ฆฌ๋ฅผ ๋์ฒดํ๋ x๋ x = y.right
์ด ๋์ด์ผ ํ๋ค.

์ ๊ทธ๋ฆผ์์ ํค๊ฐ์ด 1์ธ ๋ ธ๋๋ 2์ธ ๋ ธ๋์ ๊ฒฝ์ฐ, ๊ทธ ์์ ์ด ์ญ์ ๋๋ ๋ ธ๋์ด๋ค. ํ์ง๋ง 12๋ฅผ ํค๊ฐ์ผ๋ก ๊ฐ๋ ๋ ธ๋๋ฅผ ์ญ์ ํ๋ ๊ณผ์ ์ค์ ์ ๋ง๋ก ์ญ์ ๋๋ ๋ ธ๋๋ 12์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ์ ์ต์๊ฐ์ธ 14๋ค. ๋ฐ๋ผ์ y๋ฅผ 14๋ฒ ๋ ธ๋๋ก ์ค์ ํ๊ณ , y์ ์์ ๋ณด์์ผ ํ๋ค. red black ํธ๋ฆฌ์ ๊ฐ์ฅ ํต์ฌ์ ์ธ ์กฐ๊ฑด์ธ ํ ๋ ธ๋์์ ๋ฆฌํ๊น์ง๋ก ๊ฐ๋ ๊ฐ ๊ฒฝ๋ก์ black height๊ฐ ๋ชจ๋ ๊ฐ๋ค๋ ์กฐ๊ฑด์ ์งํค๊ธฐ ์ํด์๋, ์ค์ ๋ก ์ญ์ ๋๋ (๊ทธ๋์ ๊ทธ ์์๊ณผ ๋ถ๋ชจ๊ฐ ์๋ก ์ฐ๊ฒฐ๋๋) ๋ ธ๋์ ์์ด ์ค์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ ธ๋๋ฅผ ์ญ์ ํ ๊ฒฝ์ฐ, ์ญ์ ๋๋ ๋ ธ๋์ ์์ด black์ธ์ง, red์ธ์ง์ ๋ฐ๋ผ ์์ฑ ์๋ฐ ์ฌ๋ถ๊ฐ ๊ฒฐ์ ๋๋ค. ๋ง์ฝ ์ญ์ ๋ ๋ ธ๋๊ฐ red์ธ ๊ฒฝ์ฐ์๋ ์๋ฐ์ด ๋ฐ์ํ์ง ์๋๋ฐ, ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ญ์ ๋ ๋ ธ๋ y๊ฐ red๋ผ๊ณ ํ ๋,
- y.parent ์์ ์๋ธํธ๋ฆฌ๋ก ๊ฐ๋ ๊ฐ ๊ฒฝ๋ก์ black height๋ ๋ณํจ์ด ์์ผ๋ฏ๋ก 5๋ฒ ์์ฑ์ด ๋ณด์กด๋๋ค.
- y.color == red์ด๋ฏ๋ก, y.left/y.right์ y.parent์ ์์ black์ด๋ค. ๋ฐ๋ผ์ y๊ฐ ์ญ์ ๋๊ณ , y์ ์์ ์ค ํ๋๊ฐ y๋ฅผ ๋์ฒดํ๊ฒ ๋์ด๋ ์์ฑ4๋ฅผ ์๋ฐํ์ง ์๋๋ค.
- y๋ leaf ๋๋ root๊ฐ ์๋๋ฏ๋ก 2, 3๋ฒ ์์ฑ์ด ๋ณด์กด๋๋ค. ์์ ๋ณํ๊ฐ ์์ผ๋ฏ๋ก 1๋ฒ ์์ฑ๋ ๋ง์ฐฌ๊ฐ์ง.
ํ์ง๋ง ์ญ์ ๋ ๋ ธ๋๊ฐ black์ด๋ผ๋ฉด, ์ญ์ ํ red black์ ์์ฑ์ ๋ณต๊ตฌํ๋ ์ฐ์ฐ์ด ํ์ํ๋ค.
- Rule 2: ์ญ์ ๋ ๋ ธ๋๊ฐ ๋ฃจํธ์ธ ๊ฒฝ์ฐ, ๋ฃจํธ๊ฐ black์ด์ด์ผ ํ๋ค๋ ์กฐ๊ฑด์ด ์๋ฐ๋ ์ ์๋ค.
- Rule 4: ํ ๋ ธ๋๊ฐ ์ญ์ ๋๊ณ ๋์ ๊ทธ ์์๊ณผ ๋ถ๋ชจ๊ฐ ์ฐ๊ฒฐ๋์์ ๋, Red์ ์์์ด Red์ธ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์๋ค.
- Rule 5: ํ ๋ ธ๋๊ฐ ์ญ์ ๋๊ณ ๋์, ๊ทธ ๋ถ๋ชจ๋ก๋ถํฐ ๋ฆฌํ๋ก ๊ฐ๋ black height์ด ์๋ก ๋ฌ๋ผ์ง ์ ์๋ค.
Rule 5์ ์๋ฐ์ ์์ ํ๊ธฐ ์ํด, y๋ฅผ ๋์ฒดํ๋ ๋ ธ๋ x์ ์ฌ๋ถ์ black์ ์ถ๊ฐํด์ค ์ ์๋ค. ์ฆ, x๋ฅผ ํฌํจํ์ฌ ๋ฆฌํ๊น์ง์ ๊ฒฝ๋ก์ ํฌํจ๋๋ black์ ์๋ฅผ black_count๋ผ๊ณ ํ ๋, ํ์ฌ x์ black parent๊ฐ ์ญ์ ๋ ์ํฉ์ด๊ธฐ ๋๋ฌธ์, x์ black_count๋ x์ ํ์ ๋ ธ๋ w์ black_count๋ณด๋ค 1๋งํผ ์ ๋ค. ๋ฐ๋ผ์, x์ ์ฌ๋ถ์ black์ ์ถ๊ฐํด์ค์ผ๋ก์ black_count๋ฅผ 1 ์ฆ๊ฐ์ํจ๋ค. ์ด๋ฌํ ๋ ธ๋๋ฅผ double black์ด๋ผ๊ณ ํ๋ค. x๋ฅผ double black์ผ๋ก ํ๋ฉด 5๋ฒ ๊ท์น์ ๋ณต๊ตฌ๋์ง๋ง, ๋ชจ๋ ๋ ธ๋๊ฐ red or black์ด์ด์ผ ํ๋ค๋ 1๋ฒ ๊ท์น์ ๊นจ์ง๊ฒ ๋๋ค.
๐ค double black์ธ x๋ฅผ resolveํ ์ ์๋ ๋ฐฉ๋ฒ์? x์ ํ์ ์ธ w์ black_count๋ฅผ ๋์ผํ๊ฒ ๋ง์ถฐ์ฃผ๋ ๊ฒ์ด๋ค. ์ด๋ w๋ฅผ red๋ก ๋ง๋ค๊ฑฐ๋, x์ w์ ๋ถ๋ชจ๋ฅผ ๋ค๋ฅด๊ฒ ํ ๋ค x์๋ง black parent๋ฅผ ๋ถ์ฌ ์ค์ผ๋ก์ ํด์๋ ์ ์๊ฒ ๋ค.
์ฆ, 1๋ฒ 2๋ฒ 4๋ฒ ์์ฑ์ด ๊นจ์ง ์ ์์ผ๋ฏ๋ก, ์ญ์ ๋ ์๋ฆฌ๋ฅผ ์๋ก ์ฐจ์งํ๊ฒ ๋ ๋
ธ๋ x๊ฐ red black ์์ฑ์ ์๋ฐํ์ง ์๋๋ก ์์ ํด์ผ ํ๋ค. ์ด๋ฅผ rbtree_delete_fixup
์ด๋ผ๊ณ ํ ๋, fixup์ ์ผ์ด์ค๋ ์ด 8๊ฐ์ง๋ก ๋๋๋ค. ์ฝ์
๊ณผ ์ ์ฌํ๊ฒ, 1-4๋ 5-8๊ณผ ๋์นญ์ด๋ค.
if y.color == black
rbtree_delete_fixup(t, x)
...
rbtree_delete_fixup(rbtree* t, node_t* x)
while (x != t.root && x.color == BLACK
if x == x.parent.left
w = x.parent.right // sibling
if w.color == RED
// case 1
if w.left.color == BLACK && w.right.color == BLACK
// case 2
else
if w.left.color = BLACK
// case 3
else
// case 4
else
// symmetric to x == x.parent.left (left -> right)
// case 5 to 8
x.color = BLACK
๐ค while๋ฌธ ์์์ w๊ฐ ํญ์ nil์ด ์๋์ ๋ณด์ผ ์ ์๋๊ฐ?
- while๋ฌธ ์ง์
์ 1.
y.color == BLACK
2.x.color == BLACK
์ ๋ณด์ฅํ๋ค. - ๋ง์ฝ
w == t.nil
, y.parent๋ก๋ถํฐ leaf๊น์ง ๊ฐ๋ ๊ฒฝ๋ก์ black height์ด ๊ฐ์ง ์๊ฒ ๋๋ค. (x๊ฐ nil์ด๋๋ผ๋) - ์ด๋ legalํ red black tree์ 5๋ฒ ์์ฑ์ ์๋ฐํ๋ฏ๋ก, ์ญ์ ์ฐ์ฐ ์ ์ด๋ฌํ ๊ฒฝ์ฐ๋ ๋ฐ์ํ์ง ์๋๋ค.
CASE 0: x์ ์์ด RED์ธ ๊ฒฝ์ฐ
x์ ์์ด red์ผ ๊ฒฝ์ฐ, while๋ฌธ์ ์ง์
ํ์ง ์๊ณ x.color๋ฅผ black์ผ๋ก ๋ฐ๊พธ์ด ์ค ๋ค์ ์ข
๋ฃํ๋ค. ์ ์ด๊ฒ ๊ฐ๋ฅํ๊ฐ? x๊ฐ red์ด๊ณ y์ ์๋ฆฌ๋ฅผ ๋์ฒดํ๋ฏ๋ก, ์์ black์ผ๋ก๋ง ๋ฐ๊ฟ์ฃผ๋ฉด 5๋ฒ ์กฐ๊ฑด์ ์๋ฐ์ ํด๊ฒฐํ ์ ์๋ค. ๋ํ red node๋ root๋๋ leaf๊ฐ ๋ ์ ์์ผ๋ฏ๋ก black์ผ๋ก ๋ฐ๊ฟ์ฃผ์ด๋ ์์ฑ์ ์๋ฐํ์ง ์๋๋ค. (์ด ๊ฒฝ์ฐ fixup ํจ์์ ์ง์
ํ์๋ง์ while๋ฌธ์ ๊ฑด๋๋ฐ๊ณ x.color = BLACK
๋ผ์ธ๋ง ์ํํ ํ ์ข
๋ฃํ๋ค)
๋๋จธ์ง CASE 1-4์์๋ x.color == BLACK
์ด๋ค. ๋, w๋ฅผ x์ sibling์ผ๋ก ์ค์ ํ๋ค. (x == x.parent.left
๋ผ๋ฉด w = x.parent.right
)
CASE 1: w์ ์์ด BLACK์ธ ๊ฒฝ์ฐ

- w.color = BLACK
- x.parent.color = RED
- rotate_left(t, x.parent)
- w = x.parent.right
CASE 2-4๋ก ๊ฐ๊ธฐ ์ํ ๋จ๊ณ๋ผ๊ณ ๋ณผ ์ ์๋ค. ๋ฐ๋ผ์, w.color๋ฅผ black์ผ๋ก ๋ฐ๊ฟ์ฃผ๋, ์ด ๊ณผ์ ์์ ์์ฑ์ ๋ณด์กดํ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ค. ์ด ๊ฒฝ์ฐ, x๊ฐ ๊ฐ์ง double black์ ํด์ํ์ง ๋ชปํ๊ณ , ํ์ฐ์ ์ผ๋ก ๋ค๋ฅธ ๋จ๊ณ๋ก ๊ฐ๊ฒ ๋๋ค.
CASE 2: w์ ์์ด BLACK์ด๊ณ , w์ ์์์ด ๋ชจ๋ BLACK์ธ ๊ฒฝ์ฐ

- w.color = RED
- x = x.parent
black_count(x) = black_count(w)-1์ด๋ฏ๋ก, w.color๋ฅผ red๋ก ๋ง๋ฆ์ผ๋ก์ double black์ ํด์ํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ x๊ฐ ๋ค์ x์ ๋ถ๋ชจ๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋ง๋ฆ์ผ๋ก์ while ์กฐ๊ฑด๋ฌธ ๊ฒ์ฌ๋ฅผ ํ๋ค. ๋ง์ฝ x.color๊ฐ ์ฌ์ ํ black์ด๋ผ๋ฉด, w.color๋ฅผ red๋ก ๋ง๋ ๊ฒ์ด 4๋ฒ ์์ฑ์ ์๋ฐฐ๋์ง ์๋๋ค๊ณ ํ์ ํ ์ ์๋ค. ๊ทธ๋ฌ๋ x.color๊ฐ red๋ผ๋ฉด, while๋ฌธ์ ๋ค์ ์ง์ ํ์ง ๋ชปํ๊ณ ๋ง์ง๋ง ๋ผ์ธ์ธ x.color = BLACK์ ์ํํจ์ผ๋ก์ 4๋ฒ ์์ฑ์ ๋ณด์กดํ๋ค.
CASE 3: w์ ์์ด BLACK์ด๊ณ , w์ ์ค๋ฅธ์ชฝ ์์์ด BLACK์ธ ๊ฒฝ์ฐ

- w.color = RED
- w.left = BLACK
- rotate_right(t, w)
- w = x.parent.right
CASE 4๋ก ๊ฐ๊ธฐ ์ํ ๋จ๊ณ์ด๋ค. recoloring & rotation์ ํตํด w์ ์ค๋ฅธ์ชฝ ์์์ ์์ RED๋ก ๋ฐ๊ฟ์ค๋ค.
CASE 4: w์ ์์ด BLACK์ด๊ณ , w์ ์ค๋ฅธ์ชฝ ์์์ด RED์ธ ๊ฒฝ์ฐ (else)

- w.color = x.parent.color
- w.right.color = BLACK
- x.parent.color = BLACK
- rotate_left(t, x.parent)
- x = t.root
์ด ๊ฒฝ์ฐ, ์์ ๊ฐ์ ์ฐ์ฐ์ ํตํด x์ double black์ ์ ๊ฑฐํ ์ ์๋ค. (์ฆ, CASE 4๋ ๋ฌด์กฐ๊ฑด while loop๋ฅผ ์ข ๋ฃ์ํจ๋ค) ์ด๋ ์ฐ์ฐ์ ํตํด x์ black parent๋ฅผ ๋ถ์ฌ์ค์ผ๋ก์ x์ w๊ฐ์ black_count์ ๋ถ๊ท ํ์ ํด์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ค์ํ ๊ฒ์ ๊ฒฐ๊ตญ ์ฝ์ ๊ณผ ์ญ์ ๋ฅผ ํ๋ฉด์ ๋ ๋ ๋ธ๋ ํธ๋ฆฌ์ ์์ฑ์ ๋ง์กฑ์ํค๋ ๊ฒ์ด๋ค. ๊ทธ๋์ผ๋ง balanced tree๋ฅผ ์ํด 5๋ฒ ์์ฑ์ ๋ณด์กดํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ํ, ์ด ๋ชจ๋ ์ฐ์ฐ์ด ์ต๋ O(\logN)์ ์ํ๋จ์ด ์ค์ํ๋ค. insert_fixup์์๋ CASE1, delete_fixup์์๋ CASE2๋ง์ด ์ ์ผํ๊ฒ z๊ฐ ์๋จ์ผ๋ก ์ฌ๋ผ๊ฐ๋ ๊ฒฝ์ฐ์ด๋ค. ๋๋จธ์ง๋ ๋ชจ๋ ์์๊ฐ์ ๋กํ ์ด์ ๊ณผ recoloring๋ง์ด ์ํ๋๋ฏ๋ก, ๋ถ๋ชจ ๋๋ ์กฐ๋ถ ๋ ธ๋๋ก ์ฌ๋ผ๊ฐ๋ ๊ฒฝ์ฐ์ ์๊ฐ๋ณต์ก๋๋ง ์๊ฐํ ์ ์๋ค. ์ฆ, ํธ๋ฆฌ์ ๊ท ํ์ ์ ์งํ๋ ๋น์ฉ ์์ฒด๊ฐ (fixup์ ์๊ฐ๋ณต์ก๋๊ฐ) O(\logN)์ด๋ฏ๋ก ๋ ๋ ๋ธ๋ ํธ๋ฆฌ๋ผ๋ ์๋ฃ๊ตฌ์กฐ๊ฐ ํจ์จ์ฑ์ ๋ฌ์ฑํ ์ ์๋ ๊ฒ์ด๋ค.
'DevLog ๐จ > DataStructure' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[DevLog][DS] Red Black Tree: concept (0) | 2023.09.03 |
---|