avltree.nim 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # not really an AVL tree anymore, but still balanced ...
  10. template isBottom(n: PAvlNode): bool = n.link[0] == n
  11. proc lowGauge(n: PAvlNode): int =
  12. var it = n
  13. while not isBottom(it):
  14. result = it.key
  15. it = it.link[0]
  16. proc highGauge(n: PAvlNode): int =
  17. result = -1
  18. var it = n
  19. while not isBottom(it):
  20. result = it.upperBound
  21. it = it.link[1]
  22. proc find(root: PAvlNode, key: int): PAvlNode =
  23. var it = root
  24. while not isBottom(it):
  25. if it.key == key: return it
  26. it = it.link[ord(it.key <% key)]
  27. proc inRange(root: PAvlNode, key: int): PAvlNode =
  28. var it = root
  29. while not isBottom(it):
  30. if it.key <=% key and key <% it.upperBound: return it
  31. it = it.link[ord(it.key <% key)]
  32. proc skew(t: var PAvlNode) =
  33. if t.link[0].level == t.level:
  34. var temp = t
  35. t = t.link[0]
  36. temp.link[0] = t.link[1]
  37. t.link[1] = temp
  38. proc split(t: var PAvlNode) =
  39. if t.link[1].link[1].level == t.level:
  40. var temp = t
  41. t = t.link[1]
  42. temp.link[1] = t.link[0]
  43. t.link[0] = temp
  44. inc t.level
  45. proc add(a: var MemRegion, t: var PAvlNode, key, upperBound: int) {.benign.} =
  46. if t.isBottom:
  47. t = allocAvlNode(a, key, upperBound)
  48. else:
  49. if key <% t.key:
  50. when defined(avlcorruption):
  51. if t.link[0] == nil:
  52. cprintf("bug here %p\n", t)
  53. add(a, t.link[0], key, upperBound)
  54. elif key >% t.key:
  55. when defined(avlcorruption):
  56. if t.link[1] == nil:
  57. cprintf("bug here B %p\n", t)
  58. add(a, t.link[1], key, upperBound)
  59. else:
  60. sysAssert false, "key already exists"
  61. skew(t)
  62. split(t)
  63. proc del(a: var MemRegion, t: var PAvlNode, x: int) {.benign.} =
  64. if isBottom(t): return
  65. a.last = t
  66. if x <% t.key:
  67. del(a, t.link[0], x)
  68. else:
  69. a.deleted = t
  70. del(a, t.link[1], x)
  71. if t == a.last and not isBottom(a.deleted) and x == a.deleted.key:
  72. a.deleted.key = t.key
  73. a.deleted.upperBound = t.upperBound
  74. a.deleted = getBottom(a)
  75. t = t.link[1]
  76. deallocAvlNode(a, a.last)
  77. elif t.link[0].level < t.level-1 or
  78. t.link[1].level < t.level-1:
  79. dec t.level
  80. if t.link[1].level > t.level:
  81. t.link[1].level = t.level
  82. skew(t)
  83. skew(t.link[1])
  84. skew(t.link[1].link[1])
  85. split(t)
  86. split(t.link[1])