github.com/benz9527/toy-box/algo@v0.0.0-20240221120937-66c0c6bd5abd/tree/redblack_tree.go (about) 1 package tree 2 3 import "fmt" 4 5 const RED int = 1 6 const BLACK int = 0 7 8 type RedBlackNode struct { 9 Item int 10 Color int 11 Parent, Left, Right *RedBlackNode 12 } 13 14 // EmptyNil All value is default nil(zero) value 15 var EmptyNil *RedBlackNode = nil 16 17 type RedBlackTree struct { 18 Root *RedBlackNode 19 } 20 21 func (rbTree *RedBlackTree) PreOrder(n *RedBlackNode) { 22 if n != EmptyNil { 23 fmt.Print(n.Item, " ") 24 rbTree.PreOrder(n.Left) 25 rbTree.PreOrder(n.Right) 26 } 27 } 28 29 func (rbTree *RedBlackTree) InOrder(n *RedBlackNode) { 30 if n != EmptyNil { 31 rbTree.InOrder(n.Left) 32 fmt.Print(n.Item, " ") 33 rbTree.InOrder(n.Right) 34 } 35 } 36 37 func (rbTree *RedBlackTree) PostOrder(n *RedBlackNode) { 38 if n != EmptyNil { 39 rbTree.PostOrder(n.Left) 40 rbTree.PostOrder(n.Right) 41 fmt.Print(n.Item, " ") 42 } 43 } 44 45 func (rbTree *RedBlackTree) Search(n *RedBlackNode, k int) *RedBlackNode { 46 if n == EmptyNil || k == n.Item { 47 return n 48 } 49 50 if k < n.Item { 51 return rbTree.Search(n.Left, k) 52 } 53 return rbTree.Search(n.Right, k) 54 } 55 56 func (rbTree *RedBlackTree) LeftRotate(nx *RedBlackNode) { 57 ny := nx.Right 58 nx.Right = ny.Left 59 60 if ny.Left != EmptyNil { 61 ny.Left.Parent = nx 62 } 63 64 ny.Parent = nx.Parent 65 if nx.Parent == nil { 66 rbTree.Root = ny 67 } else if nx == nx.Parent.Left { 68 nx.Parent.Left = ny 69 } else { 70 nx.Parent.Right = ny 71 } 72 73 ny.Left = nx 74 nx.Parent = ny 75 } 76 77 func (rbTree *RedBlackTree) RightRotate(nx *RedBlackNode) { 78 ny := nx.Left 79 nx.Left = ny.Right 80 81 if ny.Right != EmptyNil { 82 ny.Right.Parent = nx 83 } 84 85 ny.Parent = nx.Parent 86 if nx.Parent == nil { 87 rbTree.Root = ny 88 } else if nx == nx.Parent.Right { 89 nx.Parent.Right = ny 90 } else { 91 nx.Parent.Left = ny 92 } 93 ny.Right = nx 94 nx.Parent = ny 95 } 96 97 func (rbTree *RedBlackTree) Insert(k int) { 98 newNode := &RedBlackNode{ 99 Parent: nil, 100 Item: k, 101 Left: EmptyNil, 102 Right: EmptyNil, 103 Color: RED, 104 } 105 106 var ny *RedBlackNode = nil 107 var nx = rbTree.Root 108 109 for nx != EmptyNil { 110 ny = nx 111 if newNode.Item < nx.Item { 112 nx = nx.Left 113 } else { 114 nx = nx.Right 115 } 116 } 117 118 newNode.Parent = ny 119 if ny == nil { 120 rbTree.Root = newNode 121 } else if newNode.Item < ny.Item { 122 ny.Left = newNode 123 } else { 124 ny.Right = newNode 125 } 126 127 if newNode.Parent == nil { 128 newNode.Color = BLACK 129 return 130 } 131 132 if newNode.Parent.Parent == nil { 133 return 134 } 135 136 rbTree.PostInsertBalance(newNode) 137 } 138 139 // PostInsertBalance Balance the node after insertion 140 func (rbTree *RedBlackTree) PostInsertBalance(target *RedBlackNode) { 141 var tmp *RedBlackNode = nil 142 for target.Parent.Color == RED { 143 if target.Parent == target.Parent.Parent.Right { 144 tmp = target.Parent.Parent.Left 145 if tmp.Color == RED { 146 tmp.Color = BLACK 147 target.Parent.Color = BLACK 148 target.Parent.Parent.Color = RED 149 target = target.Parent.Parent 150 } else { 151 if target == target.Parent.Left { 152 target = target.Parent 153 rbTree.RightRotate(target) 154 } 155 target.Parent.Color = BLACK 156 target.Parent.Parent.Color = RED 157 rbTree.LeftRotate(target.Parent.Parent) 158 } 159 } else { 160 tmp = target.Parent.Parent.Right 161 162 if tmp.Color == RED { 163 tmp.Color = BLACK 164 target.Parent.Color = BLACK 165 target.Parent.Parent.Color = RED 166 target = target.Parent.Parent 167 } else { 168 if target == target.Parent.Right { 169 target = target.Parent 170 rbTree.LeftRotate(target) 171 } 172 173 target.Parent.Color = BLACK 174 target.Parent.Parent.Color = RED 175 rbTree.RightRotate(target.Parent.Parent) 176 } 177 } 178 179 if target == rbTree.Root { 180 break 181 } 182 } 183 rbTree.Root.Color = BLACK 184 } 185 186 func (rbTree *RedBlackTree) Transplant(currentNode, childNode *RedBlackNode) { 187 if currentNode.Parent == nil { 188 rbTree.Root = childNode 189 } else if currentNode == currentNode.Parent.Left { 190 currentNode.Parent.Left = childNode 191 } else { 192 currentNode.Parent.Right = childNode 193 } 194 childNode.Parent = currentNode.Parent 195 } 196 197 func (rbTree *RedBlackTree) Minimum(n *RedBlackNode) *RedBlackNode { 198 for n.Left != EmptyNil { 199 n = n.Left 200 } 201 return n 202 } 203 204 func (rbTree *RedBlackTree) Maximum(n *RedBlackNode) *RedBlackNode { 205 for n.Right != EmptyNil { 206 n = n.Right 207 } 208 return n 209 } 210 211 func (rbTree *RedBlackTree) Successor(nx *RedBlackNode) *RedBlackNode { 212 if nx.Right != EmptyNil { 213 return rbTree.Minimum(nx.Right) 214 } 215 216 ny := nx.Parent 217 for ny != EmptyNil && 218 nx == ny.Right { 219 nx = ny 220 ny = ny.Parent 221 } 222 return ny 223 } 224 225 func (rbTree *RedBlackTree) Predecessor(nx *RedBlackNode) *RedBlackNode { 226 if nx.Left != EmptyNil { 227 return rbTree.Maximum(nx.Left) 228 } 229 230 ny := nx.Parent 231 for ny != EmptyNil && 232 nx == ny.Left { 233 nx = ny 234 ny = ny.Parent 235 } 236 return ny 237 } 238 239 func (rbTree *RedBlackTree) Delete(parentNode *RedBlackNode, k int) { 240 nz := EmptyNil 241 var nx, ny *RedBlackNode = nil, nil 242 for parentNode != EmptyNil { 243 if parentNode.Item == k { 244 nz = parentNode 245 } 246 247 if parentNode.Item <= k { 248 parentNode = parentNode.Right 249 } else { 250 parentNode = parentNode.Left 251 } 252 } 253 254 if nz == EmptyNil { 255 fmt.Println("Could not find key in the tree!") 256 return 257 } 258 259 ny = nz 260 nyOldColor := ny.Color 261 if nz.Left == EmptyNil { 262 nx = nz.Right 263 rbTree.Transplant(nz, nz.Right) 264 } else if nz.Right == EmptyNil { 265 nx = nz.Left 266 rbTree.Transplant(nz, nz.Left) 267 } else { 268 ny = rbTree.Minimum(nz.Right) 269 nyOldColor = ny.Color 270 nx = ny.Right 271 if ny.Parent == nz { 272 nx.Parent = ny 273 } else { 274 rbTree.Transplant(ny, ny.Right) 275 ny.Right = nz.Right 276 ny.Right.Parent = ny 277 } 278 279 rbTree.Transplant(nz, ny) 280 ny.Left = nz.Left 281 ny.Left.Parent = ny 282 ny.Color = nz.Color 283 } 284 285 if nyOldColor == BLACK { 286 rbTree.PostDeleteBalance(nx) 287 } 288 } 289 290 // PostDeleteBalance Balance the tree after deletion of a node 291 func (rbTree *RedBlackTree) PostDeleteBalance(nx *RedBlackNode) { 292 var ns *RedBlackNode = nil 293 for nx != rbTree.Root && 294 nx.Color == BLACK { 295 if nx == nx.Parent.Left { 296 ns = nx.Parent.Right 297 if ns.Color == RED { 298 ns.Color = BLACK 299 nx.Parent.Color = RED 300 rbTree.LeftRotate(nx.Parent) 301 ns = nx.Parent.Right 302 } 303 304 if ns.Left.Color == BLACK && 305 ns.Right.Color == BLACK { 306 ns.Color = RED 307 nx = nx.Parent 308 } else { 309 if ns.Right.Color == BLACK { 310 ns.Left.Color = BLACK 311 ns.Color = RED 312 rbTree.RightRotate(ns) 313 ns = nx.Parent.Right 314 } 315 316 ns.Color = nx.Parent.Color 317 nx.Parent.Color = BLACK 318 ns.Right.Color = BLACK 319 rbTree.LeftRotate(nx.Parent) 320 nx = rbTree.Root 321 } 322 } else { 323 ns = nx.Parent.Left 324 if ns.Color == RED { 325 ns.Color = BLACK 326 nx.Parent.Color = RED 327 rbTree.RightRotate(nx.Parent) 328 ns = nx.Parent.Left 329 } 330 331 if ns.Left.Color == BLACK && 332 ns.Right.Color == BLACK { 333 ns.Color = RED 334 nx = nx.Parent 335 } else { 336 if ns.Left.Color == BLACK { 337 ns.Right.Color = BLACK 338 ns.Color = RED 339 rbTree.LeftRotate(ns) 340 ns = nx.Parent.Left 341 } 342 343 ns.Color = nx.Parent.Color 344 nx.Parent.Color = BLACK 345 ns.Left.Color = BLACK 346 rbTree.RightRotate(nx.Parent) 347 nx = rbTree.Root 348 } 349 } 350 } 351 nx.Color = BLACK 352 }