Skip to content

Commit 651ffc2

Browse files
committedDec 18, 2020
Binary Search Tree
1 parent 8e112b9 commit 651ffc2

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed
 

‎trees/binary-search-tree.py

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
class TreeNode:
2+
def __init__(self, key=None, value=None, parent=None, left=None, right=None):
3+
self.key = key
4+
self.value = value
5+
self.parent = parent
6+
self.left = left
7+
self.right = right
8+
9+
def has_left_child(self) -> bool:
10+
return self.left is not None
11+
12+
def has_right_child(self) -> bool:
13+
return self.right is not None
14+
15+
def has_both_children(self) -> bool:
16+
return self.has_left_child() and self.has_right_child()
17+
18+
def is_leaf(self) -> bool:
19+
return not self.has_left_child() and not self.has_right_child()
20+
21+
def is_root(self) -> bool:
22+
return self.parent is None
23+
24+
def has_parent(self) -> bool:
25+
return self.parent is not None
26+
27+
def is_left_child(self) -> bool:
28+
return self.parent.left == self
29+
30+
def is_right_child(self) -> bool:
31+
return self.parent.right == self
32+
33+
def find_min(self):
34+
if self is None:
35+
return None
36+
if self.has_left_child():
37+
return self.left.find_min()
38+
else:
39+
return self
40+
41+
def find_max(self):
42+
if self is None:
43+
return None
44+
node = self
45+
while node.right is not None:
46+
node = node.right
47+
return node
48+
49+
50+
class BinarySearchTree:
51+
def __init__(self):
52+
self.root: TreeNode = None
53+
self.elements: int = 0
54+
55+
def size(self) -> int:
56+
return self.elements
57+
58+
def is_empty(self) -> bool:
59+
return self.root is None
60+
61+
def put(self, key, value):
62+
if self.is_empty():
63+
self.root = TreeNode(key, value)
64+
self.elements += 1
65+
else:
66+
self._put(self.root, key, value)
67+
68+
def _put(self, root: TreeNode, key, value):
69+
if root.key == key:
70+
root.value = value
71+
elif key < root.key:
72+
if root.has_left_child():
73+
self._put(root.left, key, value)
74+
else:
75+
root.left = TreeNode(key, value, root)
76+
self.elements += 1
77+
else:
78+
if root.has_right_child():
79+
self._put(root.right, key, value)
80+
else:
81+
root.right = TreeNode(key, value, root)
82+
83+
def get(self, key) -> TreeNode:
84+
if self.is_empty():
85+
return None
86+
else:
87+
return self._get(self.root, key)
88+
89+
def _get(self, root: TreeNode, key) -> TreeNode:
90+
if root.key == key:
91+
return root
92+
elif key < root.key:
93+
if root.has_left_child():
94+
return self._get(root.left, key)
95+
else:
96+
return None
97+
else:
98+
if root.has_right_child():
99+
return self._get(root.right, key)
100+
else:
101+
return None
102+
103+
def contains(self, key) -> bool:
104+
if self.is_empty():
105+
return None
106+
found: bool = False
107+
node: TreeNode = self.root
108+
while node is not None and not found:
109+
if node.key == key:
110+
found = True
111+
elif key < node.key:
112+
node = node.left
113+
else:
114+
node = node.right
115+
return found
116+
117+
def delete(self, key):
118+
node_to_delete: TreeNode = self.get(key)
119+
if node_to_delete is None:
120+
return
121+
if node_to_delete.is_root():
122+
if node_to_delete.is_leaf():
123+
self.root = None
124+
self.elements -= 1
125+
elif node_to_delete.has_both_children():
126+
max_node: TreeNode = node_to_delete.left.find_max()
127+
tmp_key = max_node.key
128+
tmp_value = max_node.value
129+
self.delete(tmp_key)
130+
node_to_delete.key = tmp_key
131+
node_to_delete.value = tmp_value
132+
else:
133+
if node_to_delete.has_left_child():
134+
self.root = node_to_delete.left
135+
else:
136+
self.root = node_to_delete.right
137+
self.root.parent = None
138+
self.elements -= 1
139+
else:
140+
if node_to_delete.is_leaf():
141+
if node_to_delete.is_left_child():
142+
node_to_delete.parent.left = None
143+
else:
144+
node_to_delete.parent.right = None
145+
self.elements -= 1
146+
elif node_to_delete.has_both_children():
147+
max_node: TreeNode = node_to_delete.left.find_max()
148+
tmp_key = max_node.key
149+
tmp_value = max_node.value
150+
self.delete(tmp_key)
151+
node_to_delete.key = tmp_key
152+
node_to_delete.value = tmp_value
153+
elif node_to_delete.has_left_child():
154+
self.elements -= 1
155+
if node_to_delete.is_left_child():
156+
node_to_delete.parent.left = node_to_delete.left
157+
else:
158+
node_to_delete.parent.right = node_to_delete.left
159+
node_to_delete.left.parent = node_to_delete.parent
160+
else:
161+
self.elements -= 1
162+
if node_to_delete.is_left_child():
163+
node_to_delete.parent.left = node_to_delete.right
164+
else:
165+
node_to_delete.parent.right = node_to_delete.right
166+
node_to_delete.right.parent = node_to_delete.parent
167+
168+
def find_min(self) -> TreeNode:
169+
if self.is_empty():
170+
return None
171+
node: TreeNode = self.root
172+
while node.left is not None:
173+
node = node.left
174+
return node
175+
176+
def find_max(self) -> TreeNode:
177+
if self.is_empty():
178+
return None
179+
node: TreeNode = self.root
180+
while node.right is not None:
181+
node = node.right
182+
return node

0 commit comments

Comments
 (0)
Please sign in to comment.