ν΄λ ꡬ쑰
πrbtree-lab
γ΄πsrc
γ΄ποΈdriver.c : mainμ€νν¨μ
γ΄ποΈMakefile : μ»΄νμΌ κ³Όμ λ¨μν
γ΄ποΈrbtree.c :ν¨μ ꡬν νμΌ
γ΄ποΈrbtree.h : ν€λ νμΌ
γ΄πtest
γ΄ποΈMakefile
γ΄ποΈtest-rbtree.c: ν μ€νΈ λͺ¨μ
O(logn) μκ°μ μνλλλ‘ λ³΄μ₯νλ€.
κ°κ°μ λ Έλκ° λ λ λ λΈλ μΈ μμ μμ±μ κ°μ§κ³ μλ μ΄μ§ νμ νΈλ¦¬μ΄λ€. λ°λΌμ μ΄μ§ νμ νΈλ¦¬μ μΌλ°μ μΈ μ‘°κ±΄μ λ§μ‘±νλ€.
νΈλ¦¬μ κ° λ
Έλλ color, key, left, right λ±μ νλλ₯Ό κ°λλ€.
λ λ-λΈλ νΈλ¦¬ μ½λμμ νκ³ μ‘°κ±΄μ λ€λ£¨κΈ° νΈλ¦¬νλλ‘ NILμ νννκΈ° μν΄ νλμ κ²½κ³λ
Έλ(SENTINEL)μ μ¬μ©νλ€.
NILλ
Έλμ μμ κ²μ μμ΄λ€.
ν λ
Έλμ μμ λλ λΆλͺ¨κ° μ‘΄μ¬νμ§ μμΌλ©΄ κ·Έμ λμλλ λ
Έλμ ν¬μΈν° νλλ NIL κ°μΌλ‘ μ±μμ§λ€.
ν λ
Έλ xμμ 리νλ
ΈλκΉμ§μ κ²½λ‘μ μλ λͺ¨λ κ²μ λ
Έλ(x μμ μ μ μΈ)λ₯Ό κ·Έ λ
Έλμ νμ λμ΄(black-height)λΌ νκ³ bh(x) λΌκ³ νλ€.
μλ 쑰건μ λ§μ‘±ν΄μΌ μ ν¨ν λ λ-λΈλ νΈλ¦¬κ° λλ€.
λ€μ κΈ°λ₯λ€μ μνν μ μλλ‘ RB Tree ꡬν
new_tree(): RB Tree ꡬ쑰체 μμ±left_rotation(tree, node): ν΄λΉ nodeλ₯Ό κΈ°μ€μΌλ‘ RB Tree μΌμͺ½ ν, κΈ°μ€ nodeκ° μλ€λ©΄ λ°νright_rotation(tree, node): ν΄λΉ nodeλ₯Ό κΈ°μ€μΌλ‘ RB Tree μ€λ₯Έμͺ½ νμ , κΈ°μ€ nodeκ° μλ€λ©΄ λ°νrbtree_insert(tree, key): RB Treeμ ν€ κ°μ΄ keyμΈ μλ‘μ΄ λ
Έλ μ½μ
ν λ£¨νΈ λ°νrbtree_insert_fixup(tree, node) : λ
Έλ μ½μ
ν RB Tree νΉμ± λ§μ‘±μν€κΈ° μν΄ λ
Έλμ μ λ³κ²½ λ° νμ μνrbtree_erase(tree, node) : λ
Έλμ ν€λ₯Ό μ΄μ©νμ¬ RB Treeμμ λ
Έλ μμ rbtree_delete_fixup(tree, node) : μμ μν ν RB Tree νΉμ±μ λ§μ‘±μν€κΈ° μν΄ λ
Έλμ μ λ³κ²½ λ° νμ μνtree_find(tree, key)delete_rbtree(tree) : RB Treeμ ν λΉλμλ λ©λͺ¨λ¦¬ λ°ν λ° νΈλ¦¬ μμ free_node(tree, node) : RB Tree λ΄λΆμ ν λΉλμλ λ
Έλμ λ©λͺ¨λ¦¬ λ°ν λ° λ
Έλ μμ rbtree_min(tree) : RB Tree μ λ
Έλμ€ ν€ κ°μ΄ κ°μ₯ μμ λ
Έλ λ°νrbtree_max(tree) : RB Tree μ λ
Έλμ€ ν€ κ°μ΄ κ°μ₯ ν° λ
Έλ λ°νtest_init()test_rotate()test_insert() test_insert_single(1024) test_find_single(512, 1024) test_erase_root(128) test_minmax_suite() test_to_array_suite() test_distinct_values() test_duplicate_values() test_multi_instance() RB-TREE-INSERTμ RB-TREE-DELETEμ μ°μ°μμ νΈλ¦¬λ₯Ό μμ νκΈ° λλ¬Έμ λ λλΈλ νΈλ¦¬μ νΉμ±μ μλ°ν μ μλ€.
LEFT-ROTATE(T, x)
1 y = x.right
2 x.right = y.left
3 if y.left != T.nil
4 y.left.p = x
5 y.p = x.p
6 if x.p == T.nil
7 T.root = y
8 elseif x == x.p.left
9 x.p.left = y
10 else x.p.right = y
11 y.left = x
12 x.p = y
RB-INSERT(T, z) λ₯Ό νΈμΆνλ©΄ λ
Έλ zκ° RBνΈλ¦¬ T μ μ½μ
λλ€.μ΄μ§ νμ νΈλ¦¬μ μ½μ
μ²λΌ λ
Έλ zκ° λ€μ΄κ° μμΉλ₯Ό νμνμ¬ νΈλ¦¬ Tμ μ½μ
ν λ€ μ½μ
λ λ
Έλ Zλ₯Ό λΉ¨κ° λ
Έλλ‘ μΉ νλ€.RB νΈλ¦¬μ 쑰건μ μλ°νμμ μλ μμΌλ―λ‘ RB-INSERT-FIXUP(T, z)μμ νμ κ³Ό μ λ³νμ ν΅ν΄ RBνΈλ¦¬μ 쑰건μ λ§μ‘±ν μ μλλ‘ νλ€.RB-TREE-INSERT μμ¬ μ½λRB-INSERT(T, z)
1 y = T.nil
2 x = T.root
3 while x != T.nil
4 y = x
5 if z.key < x.key
6 x = x.left
7 else x = x.right
8 z.p = y
9 if y == T.nil
10 T.root = z
11 elseif z.key < y.key
12 y.left = z
13 else y.right = z
14 z.left = T.nil
15 z.right = T.nil
16 z.color = RED
17 RB-INSERT-FIXUP(T, z)
BINARY-TREE-INSERTμ RB-TREE-INSERT μ μ°¨μ΄TREE-INSERTμ λνλλ λͺ¨λ NILμ T.nilλ‘ κ΅μ²΄λλ€.λ
Έλ zμ leftμ rightλ T.nilλ‘ μ§μ λλ€.λ
Έλ zμ μκΉμ λΉ¨κ°μμΌλ‘ μΉ νλ€.λ
Έλ zμ μμ΄ λΉ¨κ°μμΌλ‘ λλ©΄μ λ λλΈλνΈλ¦¬μ νΉμ±μ μλ°ν μ μμΌλ―λ‘ RB-INSERT-FIXUP(tree, node)λ₯Ό νΈμΆνμ¬ νΉμ±μ λ§μ‘±ν μ μλλ‘ νλ€.RB-INSERT-FIXUP(tree, node) μ λμλ
Έλ zκ° μ½μ
λλ©΄μ λ°μ κ°λ₯ν λ λλΈλνΈλ¦¬ 쑰건μ μλ° μ¬νκ²μ μ μ΄μ΄μΌνλ€.λ
Έλ zκ° λ£¨νΈμΌ λ μλ°λΉ¨κ°μ λ
Έλλ λΉ¨κ°μ μμμ κ°μ§ μ μλ€.λ
Έλ zμ λΆλͺ¨κ° λΉ¨κ°μμΌ λ μλ° RB-INSERT-FIXUP μμ¬ μ½λRB-INSERT-FIXUP(T, z)
1 while z.p.color == RED
2 if z.p == z.p.p.left
3 y = z.p.p.right
4 if y.color == RED
5 z.p.color = BLACK // case 1
6 y.color = BLACK // case 1
7 z.p.p.color = RED // case 1
8 z = z.p.p // case 1
9 else if z == z.p.right
10 z = z.p // case 2
11 LEFT-ROTATE(T, z)/ // case 2
12 z.p.color = BLACK // case 3
13 z.p.p.color = RED // case 3
14 RIGHT-ROTATE(T, z.p.p) // case 3
15 else (same for z.p as a z.p.p.right subtree) // case 4 ~ 6
16 T.root.color = BLACK
RB-INSERT-FIXUP(tree, node) λμ λ° μλ° κ²½μ°λ
Έλ zκ° μ½μ
λλ©΄μ λ°μ κ°λ₯ν λ λλΈλνΈλ¦¬ 쑰건μ μλ° μ¬νμ νμΈνκ³ κ° κ²½μ°μ λ§λ λ
Έλμ μ λ³κ²½ λ° νμ μ ν΅ν΄ λ λλΈλνΈλ¦¬ 쑰건μ λ§μ‘±ν μ μλλ‘ νλ€.κ²μ μ μ΄μ΄μΌνλ―λ‘ λ
Έλ zκ° λ£¨νΈμΌ λ μλ°λλ€.λΉ¨κ°μ λ
Έλλ λΉ¨κ°μ μμμ κ°μ§ μ μλ€.λ
Έλ zμ λΆλͺ¨κ° λΉ¨κ°μμΌ λ μλ°λλ€. λ
Έλ zμ μΌμ΄ yκ° μ μμΈ κ²½μ°z.p.pλ νμμ΄κ³ , z.p μ yλ μ μμ΄λ―λ‘,z.p.pλ₯Ό μ μμΌλ‘ μΉ νκ³ z.p μ yλ₯Ό νμνμ¬ νΉμ± 5λ₯Ό λ§μ‘±μν¬ μ μλ€.z.p.pλ₯Ό zλ‘ μ€μ νμ¬ μμ μ λ³νλ‘ RBTree μ μλ° μ¬νμ΄ μκ²Όλμ§ whileλ¬Έμ ν΅ν΄ λ€μ νμΈνλ€.λ
Έλ zμ μΌμ΄ yκ° νμμ΄λ©° λ
Έλ zκ° μ€λ₯Έμͺ½ μμμΈ κ²½μ°LEFT-ROTATEμ ν΅ν΄ κ²½μ° 3μΌλ‘ λ³κ²½νμ¬ μλ° μ¬νμ ν΄κ²°νλ€.λ
Έλ zμ μΌμ΄ yκ° νμμ΄λ©° λ
Έλ zκ° μΌμͺ½ μμμΈ κ²½μ°z.pμ μμ κ²μ μΌλ‘ λ°κΎΈκ³ , z.p.pμ μμ λΉ¨κ°μΌλ‘ λ°κΎΌλ€ RIGHT-ROTATIONμ ν΅ν΄ λ λλΈλ νΈλ¦¬ μλ° μ¬νμ ν΄κ²°νλ€. 
κ²½μ° 1 ~ 3 μ zμ λΆλͺ¨κ° μ‘°λΆλͺ¨μ μΌμͺ½ μλΈ νΈλ¦¬μΌ κ²½μ°μ, μ€λ₯Έμͺ½ μλΈ νΈλ¦¬μΌ κ²½μ°λ‘ λλ μ μκΈ° λλ¬Έμ μ΄ 6κ°μ§μ κ²½μ°κ° μκΈ΄λ€.
μμ ν λ
Έλ zμ λ체 λ
Έλ yμ λΆλͺ¨, μμλ±μ μ°κ²° μ 보λ₯Ό μμ νλ λ°©λ²κ³Όλ체 λ
Έλ yμ ν€ κ°μ μλ μμ ν λ
Έλ zμ λ³΅μ¬ ν λ체 λ
Έλ yλ₯Ό λμ μμ μν€λ λ°©λ²μ΄ μλλ°TRANSPLANT(T, u, v) μμ¬ μ½λTRANSPLANT(T, u, v)λ RB-DELETE(T, z) μμ μμ ν λ
Έλ zμ zλ₯Ό λ체ν λ
Έλ y(zλ³΄λ€ ν€ κ°μ΄ ν° κ°μ₯ μμ λ
Έλ)μ μ°κ²° κ΄κ³λ₯Ό λ°κΏμ£Όλ μν μ νλ€.RB-TRANSPLANT(T, u, v)
1 if u.p == T.nil
2 T.root = v
3 elseif u == u.p.left
4 u.p.left = v
5 else u.p.right = v
6 v.p = u:p
RB-DELETE(T, z) μμ¬ μ½λRB-DELETE(T, z)
1 y = z
2 y-original-color = y.color
3 if z.left == T.nil
4 x = z.right
5 RB-TRANSPLANT(T, z, z.right)
6 elseif z.right == T.nil
7 x = z.left
8 RB-TRANSPLANT(T, z, z.left)
9 else y = TREE-MINIMUM(z.right)
10 y-original-color = y.color
11 x = y.right
12 if y.p == z
13 x.p = y
14 else RB-TRANSPLANT(T, y, y.right)
15 y.right = z.right
16 y.right.p = y
17 RB-TRANSPLANT(T, z, y)
18 y.left = z.left
19 y.left.p = y
20 y.color = z.color
21 if y-original-color == BLACK
22 RB-DELETE-FIXUP(T, x)
RB-DELETE-FIXUP(T, x) λμ λ° μλ° κ²½μ°RB-DELETE(T, z)μμ μλ‘μ΄ λ
Έλ zκ° μμ λλ©΄μ λ체 λ
Έλ yκ° λ체λμλ€. λ°λΌμ y->rightμΈ xμ λν΄μ λΆλͺ¨λ‘ μ¬λΌκ°λ©΄μ λ°μ κ°λ₯ν λ λλΈλνΈλ¦¬ 쑰건μ μλ° μ¬νμ νμΈνκ³ κ° κ²½μ°μ λ§λ λ
Έλμ μ λ³κ²½ λ° νμ μ ν΅ν΄ λ λλΈλνΈλ¦¬ 쑰건μ λ§μ‘±ν μ μλλ‘ νλ€.
λ체 λ Έλ yμ μμ λ ΈλμΈ xλ₯Ό κΈ°μ€μΌλ‘ λΆλͺ¨λ Έλμ μΌμ΄ λ Έλμ μμ νμΈνλ©° κ° κ²½μ°μ λ§λ μ λ³ν λ° νμ νλ€.
κ²½μ° 1: xμ νμ wκ° μ μμΈ κ²½μ°
κ²½μ° 2: xμ νμ wλ νμμ΄κ³ wμ λ μμμ΄ λͺ¨λ νμμΈ κ²½μ°
κ²½μ° 3: xμ νμ wλ νμ, wμ μΌμͺ½ μμμ μ μ, wμ μ€λ₯Έμͺ½ μμμ νμμΈ κ²½μ°
κ²½μ° 4: xμ νμ wλ νμμ΄κ³ wμ μ€λ₯Έμͺ½ μμμ μ μμΈ κ²½μ°
κ²½μ° 1 ~ 4λ
λ Έλ xκ° λΆλͺ¨μ μΌμͺ½ μμμΌ λμ κ²½μ°μ΄λ―λ‘ μ€λ₯Έμͺ½ μμμΈ κ²½μ°μ κ²½μ° 1 ~ 5κ° λμΉμ μΌλ‘ λ°μκ°λ₯ νλ€.
RB-DELETE-FIXUP(T, x)μμ¬ μ½λ
1 while x != T.root and x.color == BLACK
2 if x == x.p.left
3 w = x.p.right
4 if w.color == RED
5 w.color = BLACK // case 1
6 x.p.color . RED // case 1
7 LEFT-ROTATE(T, x.p) // case 1
8 w = x.p.right // case 1
9 if w.left.color == BLACK and w.right.color == BLACK
10 w .color = RED // case 2
11 x = x.p // case 2
12 else if w.right.color == BLACK
13 w.left.color = BLACK // case 3
14 w.color = RED // case 3
15 RIGHT-ROTATE(T, w) // case 3
16 w = x.p.right // case 3
17 w.color = x.p.color // case 4
18 x.p.color = BLACK // case 4
19 w.right.color = BLACK // case 4
20 LEFT-ROTATE(T, x.p) // case 4
21 x = T.root // case 4
22 else (same thing for the opossite direction βrightβ and βleftβ exchanged) // case 5 ~ 8
23 x.color = BLACK
mallocsizeκ° 0 μ΄λΌλ©΄, malloc μ΄ λ¬΄μμ 리ν΄ν μ§λ ꡬνν λΌμ΄λΈλ¬λ¦¬ λ§λ€ λ€λ₯΄λ€. μ΄λ€ κ²½μ° λ ν¬μΈν°λ₯Ό 리ν΄ν μλ μκ³ , μ΄λ€ κ²½μ°, λμ΄ μλ ν¬μΈν°λ₯Ό 리ν΄νμ§λ§, μ¬μ© λΆκ°λ₯ν λΆλΆμ κ°λ¦¬ν€κ³ μμ μλ μλ€. μ΄λ€ κ²½μ°λ , ν΄λΉ μ£Όμκ°μ μ¬μ©νλ©΄ μλλ€.free λ‘ ν΄μ ν΄μ€μΌ νλ€.size : λ©λͺ¨λ¦¬ λΈλ‘μ ν¬κΈ°(λ°μ΄νΈ λ¨μ)void* μ΄λ―λ‘ μ¬μ©μκ° μνλ νμ
μΌλ‘ μΊμ€ν
ν΄μ€μΌ νλ€.malloc ν¨μκ° λ©λͺ¨λ¦¬ ν λΉμ μ€ν¨νμμ κ²½μ°, NULL ν¬μΈν°λ₯Ό 리ν΄νλ€.callocκ³Ό mallocμ μ°¨μ΄callocμ λμ μΌλ‘ λ©λͺ¨λ¦¬λ₯Ό ν λΉνκ³ ν λΉλ λ©λͺ¨λ¦¬ λΈλ‘μ 0μΌλ‘ μ΄κΈ°ννλ€. mallocμ λμ μΌλ‘ λ©λͺ¨λ¦¬λ₯Ό ν λΉνμ§λ§ ν λΉλ λ©λͺ¨λ¦¬λ₯Ό 0μΌλ‘ μ΄κΈ°ννμ§μλλ€.