You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.9 KiB

  1. class BSTNode:
  2. def __init__(self, value):
  3. self.value = value
  4. self.left = None
  5. self.right = None
  6. def size(self):
  7. ls = 0
  8. rs = 0
  9. if self.left is not None:
  10. ls = self.left.size()
  11. if self.right is not None:
  12. rs = self.right.size()
  13. return rs + ls + 1
  14. def height(self):
  15. lh = 0
  16. rh = 0
  17. if self.left is not None:
  18. lh = self.left.height()
  19. if self.right is not None:
  20. rh = self.right.height()
  21. return 1 + max(lh, rh)
  22. class BST:
  23. def __init__(self):
  24. self.root = None
  25. self.size = 0
  26. def clear(self):
  27. self.root = None
  28. self.size = 0
  29. def add(self, value):
  30. to_add = BSTNode(value)
  31. if self.root is None:
  32. self.root = to_add
  33. self.size += 1
  34. else:
  35. current = self.root
  36. parent = None
  37. while current is not None:
  38. if value > current.value:
  39. parent = current
  40. current = current.right
  41. elif value < current.value:
  42. parent = current
  43. current = current.left
  44. else:
  45. return
  46. if value > parent.value:
  47. parent.right = to_add
  48. else:
  49. parent.left = to_add
  50. self.size += 1
  51. def in_order(self):
  52. ret = []
  53. in_order_rec(self.root, ret)
  54. return ret
  55. def height(self):
  56. return self.root.height()
  57. class BalancedBST(BST):
  58. def by_index(self, i):
  59. instructions = []
  60. while i > 0:
  61. instructions.append(i & 1 == 0)
  62. i = (i - 1) // 2
  63. current = self.root
  64. while len(instructions) > 0:
  65. go_right = instructions.pop()
  66. if go_right:
  67. current = current.right
  68. else:
  69. current = current.left
  70. return current
  71. @classmethod
  72. def balanced(cls, list_param):
  73. tree = cls()
  74. add_rec(0, len(list_param) - 1, list_param, tree)
  75. return tree
  76. def in_order_rec(top, ret):
  77. if top is None:
  78. return
  79. if top.left:
  80. in_order_rec(top.left, ret)
  81. ret.append(top)
  82. if top.right:
  83. in_order_rec(top.right, ret)
  84. def add_rec(start, end, list_param, tree: BST):
  85. if end - start >= 0:
  86. mid = (start + end) // 2
  87. tree.add(list_param[mid])
  88. add_rec(start, mid - 1, list_param, tree)
  89. add_rec(mid + 1, end, list_param, tree)
  90. if __name__ == "__main__":
  91. test = 17
  92. list_param = list(range(test))
  93. tree = BalancedBST.balanced(list_param)
  94. tree2 = BST()
  95. for i in range(test):
  96. tree2.add(i)
  97. r = list(node.value for node in tree.in_order())
  98. r2 = list(node.value for node in tree2.in_order())
  99. assert r == r2
  100. tree.by_index(6)