github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/tree/bst/binarySearchTree.go (about) 1 package bst 2 3 import ( 4 "container/list" 5 "fmt" 6 "github.com/qiuhoude/go-web/algorithm/datastructures/stack" 7 "strings" 8 ) 9 10 // 可比较的接口 11 type Comparable interface { 12 // 比较大小 相等返回0 , 当前这个数小返回负数 ,当前数大返回正数 13 CompareTo(o Comparable) int 14 } 15 16 type node struct { 17 val Comparable // 包含的值 18 left, right *node // 左右节点 19 size int // 子节点的数量 20 depth int // 该节点的深度 21 } 22 23 type BST struct { 24 root *node // 根节点 25 } 26 27 func (t *BST) Size() int { 28 if t.root == nil { 29 return 0 30 } 31 return t.root.size 32 } 33 34 func (t *BST) IsEmpty() bool { 35 return t.Size() == 0 36 } 37 38 // 向二分搜索树中添加新的元素 39 func (t *BST) Add(e Comparable) { 40 t.root, _ = add(t.root, e, 0) 41 } 42 43 // 第二bool值表示true表示添加成功, false表示添加失败 44 func add(n *node, e Comparable, depth int) (*node, bool) { 45 if n == nil { 46 rn := &node{val: e, depth: depth} 47 rn.size++ 48 return rn, true 49 } 50 var addSuc bool 51 if e.CompareTo(n.val) < 0 { // e值小,挂载到左边 52 n.left, addSuc = add(n.left, e, depth+1) 53 } else if e.CompareTo(n.val) > 0 { // e值大,挂载到右边 54 n.right, addSuc = add(n.right, e, depth+1) 55 } else { //相等的情况先不做处理 56 } 57 if addSuc { // 添加成功让 size++ 58 n.size++ 59 } 60 return n, addSuc 61 } 62 63 // 查看是否包含此元素e 64 func (t *BST) Contains(e Comparable) bool { 65 return contains(t.root, e) 66 } 67 68 // 看以node为根的二分搜索树中是否包含元素e, 递归算法 69 func contains(n *node, e Comparable) bool { 70 if n == nil { 71 return false 72 } 73 if e.CompareTo(n.val) < 0 { 74 return contains(n.left, e) 75 } else if e.CompareTo(n.val) > 0 { 76 return contains(n.right, e) 77 } else { //e.CompareTo(n.val) == 0 78 return true 79 } 80 } 81 82 type TraverseFunc func(e Comparable) 83 84 // 前序遍历,最常见的变量方式 preOrder traverse 85 func (t *BST) PreOrder(f TraverseFunc) { 86 preOrder(t.root, f) 87 } 88 89 func preOrder(n *node, f TraverseFunc) { 90 if n == nil { 91 return 92 } 93 f(n.val) 94 preOrder(n.left, f) 95 preOrder(n.right, f) 96 } 97 98 // 中序遍历,是从小到大 99 func (t *BST) InOrder(f TraverseFunc) { 100 inOrder(t.root, f) 101 } 102 103 func inOrder(n *node, f TraverseFunc) { 104 if n == nil { 105 return 106 } 107 inOrder(n.left, f) 108 f(n.val) 109 inOrder(n.right, f) 110 } 111 112 // 后续序遍历 113 func (t *BST) PostOrder(f TraverseFunc) { 114 postOrder(t.root, f) 115 } 116 117 func postOrder(n *node, f TraverseFunc) { 118 if n == nil { 119 return 120 } 121 postOrder(n.left, f) 122 postOrder(n.right, f) 123 f(n.val) 124 } 125 126 //前序遍历 非递归的方式 NR=non recursion 127 func (t *BST) PreOrderNR(f TraverseFunc) { 128 n := t.root 129 if n == nil { 130 return 131 } 132 s := stack.New() 133 s.Push(n) 134 for !s.IsEmpty() { 135 tn, _ := s.Pop().(*node) 136 f(tn.val) 137 if tn.right != nil { 138 s.Push(tn.right) 139 } 140 if tn.left != nil { 141 s.Push(tn.left) 142 } 143 } 144 } 145 146 //前序遍历 非递归的方式2 147 func (t *BST) PreOrderNR2(f TraverseFunc) { 148 n := t.root 149 if n == nil { 150 return 151 } 152 s := stack.New() 153 for n != nil || !s.IsEmpty() { 154 for n != nil { 155 f(n.val) 156 s.Push(n) 157 n = n.left 158 } 159 n = s.Pop().(*node) 160 n = n.left 161 } 162 } 163 164 // 中序遍历非递归 165 func (t *BST) InOrderNR(f TraverseFunc) { 166 n := t.root 167 if n == nil { 168 return 169 } 170 s := stack.New() 171 for n != nil || !s.IsEmpty() { 172 for n != nil { // 找到最小的 173 s.Push(n) 174 n = n.left 175 } 176 n, _ = s.Pop().(*node) 177 f(n.val) 178 n = n.right 179 } 180 } 181 182 //中序遍历非递归的第2种方式 183 func (t *BST) InOrderNR2(f TraverseFunc) { 184 n := t.root 185 if n == nil { 186 return 187 } 188 s := stack.New() 189 for n != nil || !s.IsEmpty() { 190 if n != nil { 191 s.Push(n) 192 n = n.left 193 } else { 194 n = s.Pop().(*node) 195 f(n.val) 196 n = n.right 197 } 198 } 199 } 200 201 // 后续遍历 非递归方式 202 func (t *BST) PostOrderNR(f TraverseFunc) { 203 cur := t.root 204 if cur == nil { 205 return 206 } 207 s := stack.New() 208 var pre *node //Using a pre pointer to record the last visted node 209 for cur != nil || !s.IsEmpty() { 210 for cur != nil { 211 s.Push(cur) 212 cur = cur.left 213 } 214 cur, _ = s.Pop().(*node) 215 if cur.right == nil || pre == cur.right { 216 f(cur.val) 217 pre = cur 218 cur = nil 219 } else { 220 s.Push(cur) 221 cur = cur.right 222 } 223 } 224 } 225 226 // Morris 方式进行遍历搜索树,不借用占 只用普通的变量 227 func (t *BST) PreOrderMorris(f TraverseFunc) { 228 cur := t.root 229 if cur == nil { 230 return 231 } 232 for cur != nil { 233 if cur.left == nil { 234 f(cur.val) 235 cur = cur.right 236 } else { 237 prev := cur.left 238 for prev.right != nil && prev.right != cur { 239 prev = prev.right 240 } 241 if prev.right == nil { 242 f(cur.val) 243 prev.right = cur 244 cur = cur.left 245 } else { 246 prev.right = nil 247 cur = cur.right 248 } 249 } 250 } 251 } 252 253 func (t *BST) InOrderMorris(f TraverseFunc) { 254 cur := t.root 255 if cur == nil { 256 return 257 } 258 for cur != nil { 259 if cur.left == nil { 260 f(cur.val) 261 cur = cur.right 262 } else { 263 prev := cur.left 264 for prev.right != nil && prev.right != cur { 265 prev = prev.right 266 } 267 if prev.right == nil { 268 prev.right = cur 269 cur = cur.left 270 } else { 271 prev.right = nil 272 f(cur.val) 273 cur = cur.right 274 } 275 } 276 } 277 } 278 279 // 二分搜索树的层序遍历,也是广度遍历,借助队列的结构遍历 280 func (t *BST) LevelOrder(f TraverseFunc) { 281 if t.root == nil { 282 return 283 } 284 l := list.New() 285 l.PushBack(t.root) 286 for l.Len() != 0 { 287 n, _ := l.Remove(l.Front()).(*node) 288 f(n.val) 289 if n.left != nil { 290 l.PushBack(n.left) 291 } 292 if n.right != nil { 293 l.PushBack(n.right) 294 } 295 } 296 } 297 298 // 该树的最大深度 299 func (t *BST) MaxDepth() int { 300 return maxDepth(t.root) 301 302 //if t.root == nil { 303 // return 0 304 //} 305 //maxD := 0 306 //calcDepth(t.root, 0, &maxD) 307 //return maxD 308 309 } 310 func calcDepth(n *node, depth int, maxDepth *int) { 311 if n == nil { 312 return 313 } 314 if *maxDepth < depth+1 { 315 *maxDepth = depth + 1 316 } 317 calcDepth(n.left, depth+1, maxDepth) 318 calcDepth(n.right, depth+1, maxDepth) 319 } 320 321 func maxDepth(n *node) int { 322 if n == nil { 323 return 0 324 } 325 // 可用理解为是后序遍历 326 // 在跟父点处比较大小 327 leftDepth := maxDepth(n.left) 328 rightDepth := maxDepth(n.right) 329 return max(leftDepth, rightDepth) + 1 330 } 331 332 func minDepth(n *node) int { 333 if n == nil { 334 return 0 335 } 336 if n.left == nil { // 若左子树为空,则右子树的深度为为该节点的深度 337 return minDepth(n.right) + 1 338 } 339 if n.right == nil { 340 return minDepth(n.left) + 1 341 } 342 leftDepth := minDepth(n.left) 343 rightDepth := minDepth(n.right) 344 return min(leftDepth, rightDepth) + 1 345 } 346 347 func min(a, b int) int { 348 if a > b { 349 return b 350 } else { 351 return a 352 } 353 } 354 355 func max(a, b int) int { 356 if a > b { 357 return a 358 } else { 359 return b 360 } 361 } 362 363 // 寻找二分搜索树的最小元素 364 func (t *BST) Minimum() Comparable { 365 if t.root == nil { 366 return nil 367 } 368 return minimum(t.root).val 369 } 370 371 func minimum(n *node) *node { 372 if n.left == nil { 373 return n 374 } 375 return minimum(n.left) 376 } 377 378 // 寻找二分搜索树的最小元素 非递归方式 379 func (t *BST) MinimumNR() Comparable { 380 if t.root == nil { 381 return nil 382 } 383 tn := t.root 384 for { 385 if tn.left == nil { 386 break 387 } 388 tn = tn.left 389 } 390 return tn.val 391 } 392 393 // 寻找二分搜索树的最大元素 394 func (t *BST) Maximum() Comparable { 395 if t.root == nil { 396 return nil 397 } 398 return maximum(t.root).val 399 } 400 401 func maximum(n *node) *node { 402 if n.right == nil { 403 return n 404 } 405 return maximum(n.right) 406 } 407 408 func (t *BST) MaximumNR() Comparable { 409 if t.root == nil { 410 return nil 411 } 412 tn := t.root 413 for { 414 if tn.right == nil { 415 break 416 } 417 tn = tn.right 418 } 419 return tn.val 420 } 421 422 // 从二分搜索树中删除最小值所在节点, 返回最小值 423 func (t *BST) RemoveMin() Comparable { 424 if t.root == nil { 425 return nil 426 } 427 ret := minimum(t.root) 428 t.root = removeMin(t.root) 429 return ret.val 430 } 431 432 // 删除掉以node为根的二分搜索树中的最小节点 433 // 返回删除节点后新的二分搜索树的根 和 是否删除成功 434 func removeMin(n *node) *node { 435 if n.left == nil { 436 // 将要删除的右节点挂载父节点上,通过返回值返给服节点 437 tn := n.right 438 n.right = nil // 置空 gc回收 439 opDepth(tn, -1) 440 return tn 441 } 442 n.left = removeMin(n.left) 443 n.size-- 444 return n 445 } 446 447 // 对节点下面的所有节点进行操作 448 func opDepth(n *node, op int) { 449 if n == nil { 450 return 451 } 452 n.depth = n.depth + op 453 opDepth(n.left, op) 454 opDepth(n.right, op) 455 } 456 457 // 从二分搜索树中删除最大值所在节点 458 func (t *BST) RemoveMax() Comparable { 459 if t.root == nil { 460 return nil 461 } 462 ret := maximum(t.root) 463 t.root = removeMax(t.root) 464 return ret.val 465 } 466 467 func removeMax(n *node) *node { 468 if n.right == nil { 469 tn := n.left 470 n.left = nil 471 opDepth(tn, -1) 472 return tn 473 } 474 n.right = removeMax(n.right) 475 n.size-- 476 return n 477 } 478 479 // 移除指定元素,返回true表示移除成功 480 func (t *BST) Remove(c Comparable) bool { 481 if !t.Contains(c) { // 不存在删除失败 482 return false 483 } 484 n := remove(t.root, c) 485 t.root = n 486 return true 487 } 488 489 // 移除对应元素,返回跟节点 490 func remove(n *node, c Comparable) *node { 491 if n == nil { 492 return nil 493 } 494 if c.CompareTo(n.val) < 0 { 495 n.left = remove(n.left, c) 496 if n.left != nil { 497 n.size-- 498 } 499 return n 500 } else if c.CompareTo(n.val) > 0 { 501 n.right = remove(n.right, c) 502 if n.right != nil { 503 n.size-- 504 } 505 return n 506 } else { //相等,进行移除 507 // 以下分几种情况 508 509 // 1. 待删除节点左子树为空的情况 510 if n.left == nil { // 将右子树的数据反给上层 511 tn := n.right 512 n.left = nil 513 opDepth(tn, -1) 514 return tn 515 } 516 // 2. 待删除节点右子树为空的情况 517 if n.right == nil { 518 tn := n.left 519 n.left = nil 520 opDepth(tn, -1) 521 return tn 522 } 523 524 // 3. 左右都有数据, 525 // 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点 526 // 用这个节点顶替待删除节点的位置 527 successor := minimum(n.right) 528 successor.right = removeMin(n.right) 529 successor.left = n.left 530 successor.size = n.size - 1 531 successor.depth = n.depth 532 n.left = nil 533 n.right = nil 534 return successor 535 } 536 } 537 538 func (t *BST) String() string { 539 var sb strings.Builder 540 //generateBSTString(t.root, 0, &sb) 541 generateBSTLevelString(t.root, &sb) 542 return sb.String() 543 } 544 545 func generateBSTLevelString(n *node, sb *strings.Builder) { 546 l := list.New() 547 l.PushBack(n) 548 //curDepth := 0 549 550 curNodeCnt := 1 551 nextNodeCnt := 0 552 for l.Len() != 0 { 553 n, _ := l.Remove(l.Front()).(*node) 554 //if n.depth > curDepth { 555 // curDepth = n.depth 556 // sb.WriteRune('\n') 557 //} 558 559 sb.WriteString(fmt.Sprintf("%v ", n.val)) 560 curNodeCnt-- 561 if n.left != nil { 562 l.PushBack(n.left) 563 nextNodeCnt++ 564 } 565 if n.right != nil { 566 l.PushBack(n.right) 567 nextNodeCnt++ 568 } 569 if curNodeCnt == 0 { 570 sb.WriteRune('\n') 571 curNodeCnt = nextNodeCnt 572 nextNodeCnt = 0 573 } 574 } 575 } 576 577 func generateBSTString(n *node, depth int, sb *strings.Builder) { 578 if n == nil { 579 //generateDepthString(depth, sb) 580 //sb.WriteString("\n") 581 return 582 } 583 generateDepthString(depth, sb) 584 sb.WriteString(fmt.Sprintf("val:%v,child:%d,dh:%d\n", n.val, n.size-1, n.depth)) 585 generateBSTString(n.left, depth+1, sb) 586 generateBSTString(n.right, depth+1, sb) 587 } 588 589 func generateDepthString(depth int, sb *strings.Builder) { 590 for i := 0; i < depth; i++ { 591 sb.WriteString("--") 592 } 593 }