github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/petar/GoLLRB/llrb/llrb.go (about) 1 // Copyright 2010 Petar Maymounkov. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // A Left-Leaning Red-Black (LLRB) implementation of 2-3 balanced binary search trees, 6 // based on the following work: 7 // 8 // http://www.cs.princeton.edu/~rs/talks/LLRB/08Penn.pdf 9 // http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf 10 // http://www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java 11 // 12 // 2-3 trees (and the run-time equivalent 2-3-4 trees) are the de facto standard BST 13 // algoritms found in implementations of Python, Java, and other libraries. The LLRB 14 // implementation of 2-3 trees is a recent improvement on the traditional implementation, 15 // observed and documented by Robert Sedgewick. 16 // 17 package llrb 18 19 // Tree is a Left-Leaning Red-Black (LLRB) implementation of 2-3 trees 20 type LLRB struct { 21 count int 22 root *Node 23 } 24 25 type Node struct { 26 Item 27 Left, Right *Node // Pointers to left and right child nodes 28 Black bool // If set, the color of the link (incoming from the parent) is black 29 // In the LLRB, new nodes are always red, hence the zero-value for node 30 } 31 32 type Item interface { 33 Less(than Item) bool 34 } 35 36 // 37 func less(x, y Item) bool { 38 if x == pinf { 39 return false 40 } 41 if x == ninf { 42 return true 43 } 44 return x.Less(y) 45 } 46 47 // Inf returns an Item that is "bigger than" any other item, if sign is positive. 48 // Otherwise it returns an Item that is "smaller than" any other item. 49 func Inf(sign int) Item { 50 if sign == 0 { 51 panic("sign") 52 } 53 if sign > 0 { 54 return pinf 55 } 56 return ninf 57 } 58 59 var ( 60 ninf = nInf{} 61 pinf = pInf{} 62 ) 63 64 type nInf struct{} 65 66 func (nInf) Less(Item) bool { 67 return true 68 } 69 70 type pInf struct{} 71 72 func (pInf) Less(Item) bool { 73 return false 74 } 75 76 // New() allocates a new tree 77 func New() *LLRB { 78 return &LLRB{} 79 } 80 81 // SetRoot sets the root node of the tree. 82 // It is intended to be used by functions that deserialize the tree. 83 func (t *LLRB) SetRoot(r *Node) { 84 t.root = r 85 } 86 87 // Root returns the root node of the tree. 88 // It is intended to be used by functions that serialize the tree. 89 func (t *LLRB) Root() *Node { 90 return t.root 91 } 92 93 // Len returns the number of nodes in the tree. 94 func (t *LLRB) Len() int { return t.count } 95 96 // Has returns true if the tree contains an element whose order is the same as that of key. 97 func (t *LLRB) Has(key Item) bool { 98 return t.Get(key) != nil 99 } 100 101 // Get retrieves an element from the tree whose order is the same as that of key. 102 func (t *LLRB) Get(key Item) Item { 103 h := t.root 104 for h != nil { 105 switch { 106 case less(key, h.Item): 107 h = h.Left 108 case less(h.Item, key): 109 h = h.Right 110 default: 111 return h.Item 112 } 113 } 114 return nil 115 } 116 117 // Min returns the minimum element in the tree. 118 func (t *LLRB) Min() Item { 119 h := t.root 120 if h == nil { 121 return nil 122 } 123 for h.Left != nil { 124 h = h.Left 125 } 126 return h.Item 127 } 128 129 // Max returns the maximum element in the tree. 130 func (t *LLRB) Max() Item { 131 h := t.root 132 if h == nil { 133 return nil 134 } 135 for h.Right != nil { 136 h = h.Right 137 } 138 return h.Item 139 } 140 141 func (t *LLRB) ReplaceOrInsertBulk(items ...Item) { 142 for _, i := range items { 143 t.ReplaceOrInsert(i) 144 } 145 } 146 147 func (t *LLRB) InsertNoReplaceBulk(items ...Item) { 148 for _, i := range items { 149 t.InsertNoReplace(i) 150 } 151 } 152 153 // ReplaceOrInsert inserts item into the tree. If an existing 154 // element has the same order, it is removed from the tree and returned. 155 func (t *LLRB) ReplaceOrInsert(item Item) Item { 156 if item == nil { 157 panic("inserting nil item") 158 } 159 var replaced Item 160 t.root, replaced = t.replaceOrInsert(t.root, item) 161 t.root.Black = true 162 if replaced == nil { 163 t.count++ 164 } 165 return replaced 166 } 167 168 func (t *LLRB) replaceOrInsert(h *Node, item Item) (*Node, Item) { 169 if h == nil { 170 return newNode(item), nil 171 } 172 173 h = walkDownRot23(h) 174 175 var replaced Item 176 if less(item, h.Item) { // BUG 177 h.Left, replaced = t.replaceOrInsert(h.Left, item) 178 } else if less(h.Item, item) { 179 h.Right, replaced = t.replaceOrInsert(h.Right, item) 180 } else { 181 replaced, h.Item = h.Item, item 182 } 183 184 h = walkUpRot23(h) 185 186 return h, replaced 187 } 188 189 // InsertNoReplace inserts item into the tree. If an existing 190 // element has the same order, both elements remain in the tree. 191 func (t *LLRB) InsertNoReplace(item Item) { 192 if item == nil { 193 panic("inserting nil item") 194 } 195 t.root = t.insertNoReplace(t.root, item) 196 t.root.Black = true 197 t.count++ 198 } 199 200 func (t *LLRB) insertNoReplace(h *Node, item Item) *Node { 201 if h == nil { 202 return newNode(item) 203 } 204 205 h = walkDownRot23(h) 206 207 if less(item, h.Item) { 208 h.Left = t.insertNoReplace(h.Left, item) 209 } else { 210 h.Right = t.insertNoReplace(h.Right, item) 211 } 212 213 return walkUpRot23(h) 214 } 215 216 // Rotation driver routines for 2-3 algorithm 217 218 func walkDownRot23(h *Node) *Node { return h } 219 220 func walkUpRot23(h *Node) *Node { 221 if isRed(h.Right) && !isRed(h.Left) { 222 h = rotateLeft(h) 223 } 224 225 if isRed(h.Left) && isRed(h.Left.Left) { 226 h = rotateRight(h) 227 } 228 229 if isRed(h.Left) && isRed(h.Right) { 230 flip(h) 231 } 232 233 return h 234 } 235 236 // Rotation driver routines for 2-3-4 algorithm 237 238 func walkDownRot234(h *Node) *Node { 239 if isRed(h.Left) && isRed(h.Right) { 240 flip(h) 241 } 242 243 return h 244 } 245 246 func walkUpRot234(h *Node) *Node { 247 if isRed(h.Right) && !isRed(h.Left) { 248 h = rotateLeft(h) 249 } 250 251 if isRed(h.Left) && isRed(h.Left.Left) { 252 h = rotateRight(h) 253 } 254 255 return h 256 } 257 258 // DeleteMin deletes the minimum element in the tree and returns the 259 // deleted item or nil otherwise. 260 func (t *LLRB) DeleteMin() Item { 261 var deleted Item 262 t.root, deleted = deleteMin(t.root) 263 if t.root != nil { 264 t.root.Black = true 265 } 266 if deleted != nil { 267 t.count-- 268 } 269 return deleted 270 } 271 272 // deleteMin code for LLRB 2-3 trees 273 func deleteMin(h *Node) (*Node, Item) { 274 if h == nil { 275 return nil, nil 276 } 277 if h.Left == nil { 278 return nil, h.Item 279 } 280 281 if !isRed(h.Left) && !isRed(h.Left.Left) { 282 h = moveRedLeft(h) 283 } 284 285 var deleted Item 286 h.Left, deleted = deleteMin(h.Left) 287 288 return fixUp(h), deleted 289 } 290 291 // DeleteMax deletes the maximum element in the tree and returns 292 // the deleted item or nil otherwise 293 func (t *LLRB) DeleteMax() Item { 294 var deleted Item 295 t.root, deleted = deleteMax(t.root) 296 if t.root != nil { 297 t.root.Black = true 298 } 299 if deleted != nil { 300 t.count-- 301 } 302 return deleted 303 } 304 305 func deleteMax(h *Node) (*Node, Item) { 306 if h == nil { 307 return nil, nil 308 } 309 if isRed(h.Left) { 310 h = rotateRight(h) 311 } 312 if h.Right == nil { 313 return nil, h.Item 314 } 315 if !isRed(h.Right) && !isRed(h.Right.Left) { 316 h = moveRedRight(h) 317 } 318 var deleted Item 319 h.Right, deleted = deleteMax(h.Right) 320 321 return fixUp(h), deleted 322 } 323 324 // Delete deletes an item from the tree whose key equals key. 325 // The deleted item is return, otherwise nil is returned. 326 func (t *LLRB) Delete(key Item) Item { 327 var deleted Item 328 t.root, deleted = t.delete(t.root, key) 329 if t.root != nil { 330 t.root.Black = true 331 } 332 if deleted != nil { 333 t.count-- 334 } 335 return deleted 336 } 337 338 func (t *LLRB) delete(h *Node, item Item) (*Node, Item) { 339 var deleted Item 340 if h == nil { 341 return nil, nil 342 } 343 if less(item, h.Item) { 344 if h.Left == nil { // item not present. Nothing to delete 345 return h, nil 346 } 347 if !isRed(h.Left) && !isRed(h.Left.Left) { 348 h = moveRedLeft(h) 349 } 350 h.Left, deleted = t.delete(h.Left, item) 351 } else { 352 if isRed(h.Left) { 353 h = rotateRight(h) 354 } 355 // If @item equals @h.Item and no right children at @h 356 if !less(h.Item, item) && h.Right == nil { 357 return nil, h.Item 358 } 359 // PETAR: Added 'h.Right != nil' below 360 if h.Right != nil && !isRed(h.Right) && !isRed(h.Right.Left) { 361 h = moveRedRight(h) 362 } 363 // If @item equals @h.Item, and (from above) 'h.Right != nil' 364 if !less(h.Item, item) { 365 var subDeleted Item 366 h.Right, subDeleted = deleteMin(h.Right) 367 if subDeleted == nil { 368 panic("logic") 369 } 370 deleted, h.Item = h.Item, subDeleted 371 } else { // Else, @item is bigger than @h.Item 372 h.Right, deleted = t.delete(h.Right, item) 373 } 374 } 375 376 return fixUp(h), deleted 377 } 378 379 // Internal node manipulation routines 380 381 func newNode(item Item) *Node { return &Node{Item: item} } 382 383 func isRed(h *Node) bool { 384 if h == nil { 385 return false 386 } 387 return !h.Black 388 } 389 390 func rotateLeft(h *Node) *Node { 391 x := h.Right 392 if x.Black { 393 panic("rotating a black link") 394 } 395 h.Right = x.Left 396 x.Left = h 397 x.Black = h.Black 398 h.Black = false 399 return x 400 } 401 402 func rotateRight(h *Node) *Node { 403 x := h.Left 404 if x.Black { 405 panic("rotating a black link") 406 } 407 h.Left = x.Right 408 x.Right = h 409 x.Black = h.Black 410 h.Black = false 411 return x 412 } 413 414 // REQUIRE: Left and Right children must be present 415 func flip(h *Node) { 416 h.Black = !h.Black 417 h.Left.Black = !h.Left.Black 418 h.Right.Black = !h.Right.Black 419 } 420 421 // REQUIRE: Left and Right children must be present 422 func moveRedLeft(h *Node) *Node { 423 flip(h) 424 if isRed(h.Right.Left) { 425 h.Right = rotateRight(h.Right) 426 h = rotateLeft(h) 427 flip(h) 428 } 429 return h 430 } 431 432 // REQUIRE: Left and Right children must be present 433 func moveRedRight(h *Node) *Node { 434 flip(h) 435 if isRed(h.Left.Left) { 436 h = rotateRight(h) 437 flip(h) 438 } 439 return h 440 } 441 442 func fixUp(h *Node) *Node { 443 if isRed(h.Right) { 444 h = rotateLeft(h) 445 } 446 447 if isRed(h.Left) && isRed(h.Left.Left) { 448 h = rotateRight(h) 449 } 450 451 if isRed(h.Left) && isRed(h.Right) { 452 flip(h) 453 } 454 455 return h 456 }