-
Notifications
You must be signed in to change notification settings - Fork 0
/
insert.go
78 lines (69 loc) · 1.36 KB
/
insert.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package rbtree
// Insert value into the red-black tree. Returns whether a new value was
// inserted.
func (r *RedBlackTree) Insert(value interface{}) bool {
inserted := &node{value: value}
if r.root == nil {
r.root = inserted
} else {
n := r.root
for {
cmp := r.Compare(value, n.value)
if cmp == 0 {
return false
}
if cmp < 0 {
if n.left == nil {
n.left = inserted
break
}
n = n.left
} else {
if n.right == nil {
n.right = inserted
break
}
n = n.right
}
}
inserted.parent = n
}
r.insertCases(inserted)
r.size++
return true
}
func (r *RedBlackTree) insertCases(n *node) {
// case 1
if n.parent == nil {
n.color = black
return
}
// case 2
if n.parent.color == black {
return
}
// case 3
if n.parent.sibling().defcolor() == red {
n.parent.color = black
n.parent.sibling().color = black
n.parent.parent.color = red
r.insertCases(n.parent.parent)
return
}
// case 4
if n == n.parent.right && n.parent == n.parent.parent.left {
r.rotateLeft(n.parent)
n = n.left
} else if n == n.parent.left && n.parent == n.parent.parent.right {
r.rotateRight(n.parent)
n = n.right
}
// case 5
n.parent.color = black
n.parent.parent.color = red
if n == n.parent.left && n.parent == n.parent.parent.left {
r.rotateRight(n.parent.parent)
} else {
r.rotateLeft(n.parent.parent)
}
}