github.com/joshvarga/voronoi@v0.0.0-20180211004454-2fd26fbdfffb/bt_tree.go (about) 1 // MIT License: See https://github.com/pzsz/voronoi/LICENSE.md 2 3 // Author: Przemyslaw Szczepaniak (przeszczep@gmail.com) 4 // Port of Raymond Hill's (rhill@raymondhill.net) javascript implementation 5 // of Steven Forune's algorithm to compute Voronoi diagrams 6 7 package voronoi 8 9 // Red-Black tree code (based on C version of "rbtree" by Franck Bui-Huu 10 // https://github.com/fbuihuu/libtree/blob/master/rb.c 11 type rbTree struct { 12 root *rbNode 13 } 14 15 type rbNodeValue interface { 16 bindToNode(node *rbNode) 17 getNode() *rbNode 18 } 19 20 type rbNode struct { 21 value rbNodeValue 22 left *rbNode 23 right *rbNode 24 parent *rbNode 25 previous *rbNode 26 next *rbNode 27 red bool 28 } 29 30 func (t *rbTree) insertSuccessor(node *rbNode, vsuccessor rbNodeValue) { 31 successor := &rbNode{value: vsuccessor} 32 vsuccessor.bindToNode(successor) 33 34 var parent *rbNode 35 if node != nil { 36 // >>> rhill 2011-05-27: Performance: cache previous/next nodes 37 successor.previous = node 38 successor.next = node.next 39 if node.next != nil { 40 node.next.previous = successor 41 } 42 node.next = successor 43 // <<< 44 if node.right != nil { 45 // in-place expansion of node.rbRight.getFirst() 46 node = node.right 47 for ; node.left != nil; node = node.left { 48 } 49 node.left = successor 50 } else { 51 node.right = successor 52 } 53 parent = node 54 55 // rhill 2011-06-07: if node is null, successor must be inserted 56 // to the left-most part of the tree 57 } else if t.root != nil { 58 node = t.getFirst(t.root) 59 // >>> Performance: cache previous/next nodes 60 successor.previous = nil 61 successor.next = node 62 node.previous = successor 63 // <<< 64 node.left = successor 65 parent = node 66 } else { 67 // >>> Performance: cache previous/next nodes 68 successor.previous = nil 69 successor.next = nil 70 // <<< 71 t.root = successor 72 parent = nil 73 } 74 successor.left = nil 75 successor.right = nil 76 successor.parent = parent 77 successor.red = true 78 // Fixup the modified tree by recoloring nodes and performing 79 // rotations (2 at most) hence the red-black tree properties are 80 // preserved. 81 var grandpa, uncle *rbNode 82 node = successor 83 for parent != nil && parent.red { 84 grandpa = parent.parent 85 if parent == grandpa.left { 86 uncle = grandpa.right 87 if uncle != nil && uncle.red { 88 parent.red = false 89 uncle.red = false 90 grandpa.red = true 91 node = grandpa 92 } else { 93 if node == parent.right { 94 t.rotateLeft(parent) 95 node = parent 96 parent = node.parent 97 } 98 parent.red = false 99 grandpa.red = true 100 t.rotateRight(grandpa) 101 } 102 } else { 103 uncle = grandpa.left 104 if uncle != nil && uncle.red { 105 parent.red = false 106 uncle.red = false 107 grandpa.red = true 108 node = grandpa 109 } else { 110 if node == parent.left { 111 t.rotateRight(parent) 112 node = parent 113 parent = node.parent 114 } 115 parent.red = false 116 grandpa.red = true 117 t.rotateLeft(grandpa) 118 } 119 } 120 parent = node.parent 121 } 122 t.root.red = false 123 } 124 125 func (t *rbTree) removeNode(node *rbNode) { 126 // >>> rhill 2011-05-27: Performance: cache previous/next nodes 127 if node.next != nil { 128 node.next.previous = node.previous 129 } 130 if node.previous != nil { 131 node.previous.next = node.next 132 } 133 node.next = nil 134 node.previous = nil 135 // <<< 136 var parent = node.parent 137 var left = node.left 138 var right = node.right 139 var next *rbNode 140 if left == nil { 141 next = right 142 } else if right == nil { 143 next = left 144 } else { 145 next = t.getFirst(right) 146 } 147 if parent != nil { 148 if parent.left == node { 149 parent.left = next 150 } else { 151 parent.right = next 152 } 153 } else { 154 t.root = next 155 } 156 // enforce red-black rules 157 isRed := false 158 if left != nil && right != nil { 159 isRed = next.red 160 next.red = node.red 161 next.left = left 162 left.parent = next 163 if next != right { 164 parent = next.parent 165 next.parent = node.parent 166 node = next.right 167 parent.left = node 168 next.right = right 169 right.parent = next 170 } else { 171 next.parent = parent 172 parent = next 173 node = next.right 174 } 175 } else { 176 isRed = node.red 177 node = next 178 } 179 // 'node' is now the sole successor's child and 'parent' its 180 // new parent (since the successor can have been moved) 181 if node != nil { 182 node.parent = parent 183 } 184 // the 'easy' cases 185 if isRed { 186 return 187 } 188 if node != nil && node.red { 189 node.red = false 190 return 191 } 192 // the other cases 193 var sibling *rbNode 194 for { 195 if node == t.root { 196 break 197 } 198 if node == parent.left { 199 sibling = parent.right 200 if sibling.red { 201 sibling.red = false 202 parent.red = true 203 t.rotateLeft(parent) 204 sibling = parent.right 205 } 206 if (sibling.left != nil && sibling.left.red) || (sibling.right != nil && sibling.right.red) { 207 if sibling.right == nil || !sibling.right.red { 208 sibling.left.red = false 209 sibling.red = true 210 t.rotateRight(sibling) 211 sibling = parent.right 212 } 213 sibling.red = parent.red 214 parent.red = false 215 sibling.right.red = false 216 t.rotateLeft(parent) 217 node = t.root 218 break 219 } 220 } else { 221 sibling = parent.left 222 if sibling.red { 223 sibling.red = false 224 parent.red = true 225 t.rotateRight(parent) 226 sibling = parent.left 227 } 228 if (sibling.left != nil && sibling.left.red) || (sibling.right != nil && sibling.right.red) { 229 if sibling.left == nil || !sibling.left.red { 230 sibling.right.red = false 231 sibling.red = true 232 t.rotateLeft(sibling) 233 sibling = parent.left 234 } 235 sibling.red = parent.red 236 parent.red = false 237 sibling.left.red = false 238 t.rotateRight(parent) 239 node = t.root 240 break 241 } 242 } 243 sibling.red = true 244 node = parent 245 parent = parent.parent 246 if node.red { 247 break 248 } 249 } 250 if node != nil { 251 node.red = false 252 } 253 } 254 255 func (t *rbTree) rotateLeft(node *rbNode) { 256 var p = node 257 var q = node.right // can't be null 258 var parent = p.parent 259 if parent != nil { 260 if parent.left == p { 261 parent.left = q 262 } else { 263 parent.right = q 264 } 265 } else { 266 t.root = q 267 } 268 q.parent = parent 269 p.parent = q 270 p.right = q.left 271 if p.right != nil { 272 p.right.parent = p 273 } 274 q.left = p 275 } 276 277 func (t *rbTree) rotateRight(node *rbNode) { 278 var p = node 279 var q = node.left // can't be null 280 var parent = p.parent 281 if parent != nil { 282 if parent.left == p { 283 parent.left = q 284 } else { 285 parent.right = q 286 } 287 } else { 288 t.root = q 289 } 290 q.parent = parent 291 p.parent = q 292 p.left = q.right 293 if p.left != nil { 294 p.left.parent = p 295 } 296 q.right = p 297 } 298 299 func (t *rbTree) getFirst(node *rbNode) *rbNode { 300 for node.left != nil { 301 node = node.left 302 } 303 return node 304 } 305 306 func (t *rbTree) getLast(node *rbNode) *rbNode { 307 for node.right != nil { 308 node = node.right 309 } 310 return node 311 }