tbintree2.nim 2.5 KB

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