Skip to content

Commit 22aacb3

Browse files
committed
Add 4.11
1 parent 07c6498 commit 22aacb3

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

chapter_4/p4_11.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from utils.graphs import BiNode
2+
from utils.treeviz import viz_tree
3+
import random
4+
5+
class SizedNode(BiNode):
6+
def __init__(self, val: int):
7+
super().__init__(val)
8+
self.size = 1
9+
10+
def insert(self, x: int):
11+
if x > self.val:
12+
if self.right:
13+
self.right.insert(x)
14+
else:
15+
self.right = SizedNode(x)
16+
else:
17+
if self.left:
18+
self.left.insert(x)
19+
else:
20+
self.left = SizedNode(x)
21+
self.size += 1
22+
23+
24+
class BinarySearchTree:
25+
26+
def __init__(self):
27+
self.root = None
28+
29+
def add(self, x: int):
30+
if not self.root:
31+
self.root = SizedNode(x)
32+
else:
33+
self.root.insert(x)
34+
35+
def getRandomNuber(self) -> int:
36+
target = random.randint(1, self.root.size)
37+
print(f"Target is {target}")
38+
return self._get_inorder_number(self.root, target)
39+
40+
def _get_inorder_number(self, node: SizedNode, target:int) -> int:
41+
right_size = node.right.size if node.right else 0
42+
# print(f"Node is {node.val}\tsize is {node.size},\tright is {right_size}")
43+
node_traversal_poz = node.size - right_size
44+
# print(f"At poz {node_traversal_poz},\ttarget is target {target}")
45+
if node_traversal_poz == target:
46+
return node.val
47+
elif node_traversal_poz < target:
48+
return self._get_inorder_number(node.right, target - node_traversal_poz)
49+
else:
50+
return self._get_inorder_number(node.left, target)
51+
52+
53+
if __name__ == "__main__":
54+
stream = [5, 1, 4, 14, 15, 9, 7, 13, 3]
55+
rbst = BinarySearchTree()
56+
for x in stream:
57+
rbst.add(x)
58+
59+
viz_tree(rbst.root)
60+
print(rbst.root.size)
61+
print(f"Getting a random node: {rbst.getRandomNuber()}")

0 commit comments

Comments
 (0)