tbintree2.nim 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. discard """
  2. cmd: '''nim c -d:nimAllocStats --newruntime $file'''
  3. output: '''0
  4. (allocCount: 5, deallocCount: 5)'''
  5. """
  6. import system / ansi_c
  7. import random
  8. type Node = ref object
  9. x, y: int32
  10. left, right: owned Node
  11. proc newNode(x: int32): owned Node =
  12. result = Node(x: x, y: rand(high int32).int32)
  13. proc merge(lower, greater: owned Node): owned Node =
  14. if lower.isNil:
  15. result = greater
  16. elif greater.isNil:
  17. result = lower
  18. elif lower.y < greater.y:
  19. lower.right = merge(move lower.right, greater)
  20. result = lower
  21. else:
  22. greater.left = merge(lower, move greater.left)
  23. result = greater
  24. proc splitBinary(orig: owned Node, value: int32): (owned Node, owned Node) =
  25. if orig.isNil:
  26. result = (nil, nil)
  27. elif orig.x < value:
  28. let splitPair = splitBinary(move orig.right, value)
  29. orig.right = splitPair[0]
  30. result = (orig, splitPair[1])
  31. else:
  32. let splitPair = splitBinary(move orig.left, value)
  33. orig.left = splitPair[1]
  34. result = (splitPair[0], orig)
  35. proc merge3(lower, equal, greater: owned Node): owned Node =
  36. merge(merge(lower, equal), greater)
  37. proc split(orig: owned Node, value: int32): tuple[lower, equal, greater: owned Node] =
  38. let
  39. (lower, equalGreater) = splitBinary(orig, value)
  40. (equal, greater) = splitBinary(equalGreater, value + 1)
  41. result = (lower, equal, greater)
  42. type Tree = object
  43. root: owned Node
  44. proc `=destroy`(t: var Tree) {.nodestroy.} =
  45. var s: seq[owned Node] = @[t.root]
  46. while s.len > 0:
  47. let x = s.pop
  48. if x.left != nil: s.add(x.left)
  49. if x.right != nil: s.add(x.right)
  50. `=dispose`(x)
  51. `=destroy`(s)
  52. proc hasValue(self: var Tree, x: int32): bool =
  53. let splited = split(move self.root, x)
  54. result = not splited.equal.isNil
  55. self.root = merge3(splited.lower, splited.equal, splited.greater)
  56. proc insert(self: var Tree, x: int32) =
  57. var splited = split(move self.root, x)
  58. if splited.equal.isNil:
  59. splited.equal = newNode(x)
  60. self.root = merge3(splited.lower, splited.equal, splited.greater)
  61. proc erase(self: var Tree, x: int32) =
  62. let splited = split(move self.root, x)
  63. self.root = merge(splited.lower, splited.greater)
  64. proc main() =
  65. var
  66. tree = Tree()
  67. cur = 5'i32
  68. res = 0
  69. for i in 1 ..< 10:
  70. let a = i mod 3
  71. cur = (cur * 57 + 43) mod 10007
  72. case a:
  73. of 0:
  74. tree.insert(cur)
  75. of 1:
  76. tree.erase(cur)
  77. of 2:
  78. if tree.hasValue(cur):
  79. res += 1
  80. else:
  81. discard
  82. echo res
  83. dumpAllocStats:
  84. main()