Skip to content

Commit 6abb96e

Browse files
committed
Create Binary_Search_Tree.py
1 parent b886da8 commit 6abb96e

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed
+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
"""
2+
A binary search tree is a rooted binary tree, whose internal nodes each
3+
store a key (and optionally, an associated value) and each have two
4+
distinguished sub-trees, commonly denoted left and right.
5+
6+
The tree additionally satisfies the binary search property, which states that
7+
the key in each node must be greater than or equal to any key stored in the
8+
left sub-tree, and less than or equal to any key stored in the right sub-tree.
9+
10+
https://en.wikipedia.org/wiki/Binary_search_tree
11+
12+
"""
13+
14+
from random import randint
15+
16+
class Node: # class to create nodes
17+
def __init__(self, Parent = None, Value = None, Left = None, Right = None):
18+
self.parent = Parent # points to parent of Node
19+
self.value = Value # value in Node
20+
self.left = Left # points to left child
21+
self.right = Right # points to right child
22+
23+
def __str__(self):
24+
return str(self.value)
25+
26+
class BST:
27+
28+
def __init__(self):
29+
self.__root = None # initially root = None
30+
31+
def is_empty(self):
32+
return self.__root == None
33+
34+
def insert(self, val):
35+
if( self.is_empty() ): # if root = None (no nodes added to tree)
36+
self.__root = Node(Value = val) # create new node & assign to root
37+
else:
38+
current = self.__root # current node = root (initially)
39+
while( current != None ):
40+
parent = current
41+
current = current.left if( val <= current.value ) else current.right # if val < current.value, goto left child, else goto right child
42+
43+
if( val <= parent.value ): # if val < parent.value
44+
parent.left = Node(parent, val) # assign new node as Left child
45+
else:
46+
parent.right = Node(parent, val) # assign new node as Right child
47+
48+
def preorder(self, current = -1):
49+
if (current == -1 ): current = self.__root # if current == -1 (no argument passed), current = root
50+
51+
# Pre-Order = (Root, Left, Right)
52+
Ret = []
53+
if(current != None):
54+
Ret.append(current.value) # Root (value)
55+
Ret.extend(self.preorder(current.left)) # Left (subtree)
56+
Ret.extend(self.preorder(current.right)) # Right (subtree)
57+
return Ret
58+
59+
def inorder(self, current = -1):
60+
if (current == -1 ): current = self.__root # if current == -1 (no argument passed), set current = root
61+
62+
# In-Order = (Left, Root, Right)
63+
Ret = []
64+
if(current != None):
65+
Ret.extend(self.inorder(current.left)) # Left (subtree)
66+
Ret.append(current.value) # Root (value)
67+
Ret.extend(self.inorder(current.right)) # Right (subtree)
68+
return Ret
69+
70+
def postorder(self, current = -1):
71+
if (current == -1 ): current = self.__root # if current == -1 (no argument passed), set current = root
72+
73+
# Post-Order = (Left, Right, Root)
74+
Ret = []
75+
if(current != None):
76+
Ret.extend(self.postorder(current.left)) # Left (subtree)
77+
Ret.extend(self.postorder(current.right)) # Right (subtree)
78+
Ret.append(current.value) # Root (value)
79+
return Ret
80+
81+
def levelorder(self, current = -1):
82+
83+
Ret = []
84+
85+
if( self.is_empty() ): return Ret # if tree is empty, return empty list
86+
87+
if( current == -1 ):
88+
current = [self.__root] # if current == -1 (no argument passed), set current = [root]
89+
Ret.append(self.__root.value) # append root.value to Ret
90+
91+
next_level = [] # list of all nodes on Next Level
92+
93+
for each in current: # current -> list of all nodes on any particular level
94+
95+
if( each.left != None ): # if node on current level has left child
96+
Ret.append(each.left.value) # insert its value to Ret
97+
next_level.append(each.left) # add left child to next_level
98+
99+
if( each.right != None ): # if node on current level has right child
100+
Ret.append(each.right.value) # insert its value to Ret
101+
next_level.append(each.right) # add right child to next_level
102+
103+
if( next_level ): # if there are any nodes in the next_level
104+
Ret.extend(self.levelorder(next_level)) # process nodes in next_level
105+
106+
return Ret
107+
108+
def search(self, find):
109+
current = self.__root
110+
111+
while current and current.value != find : # while current (current != None) and value is not found
112+
current = current.right if(current.value < find) else current.left # if "find" is larger than current.value, traverse Right sub-tree, else left sub-tree
113+
114+
return current # return Node (None if value not found)
115+
116+
def maximum(self, current = -1):
117+
if current == -1: # find maximum of current sub tree, if argument is not passed, use root
118+
current = self.__root
119+
120+
while current and current.right != None : # while current != None & current has a right child
121+
current = current.right
122+
return current
123+
124+
def minimum(self, current = -1):
125+
if current == -1: # find minimum of current sub tree, if argument is not passed, use root
126+
current = self.__root
127+
128+
while current and current.left != None : # while current != None & current has a left child
129+
current = current.left
130+
return current
131+
132+
def successor(self, node):
133+
134+
if node.right == None: # if node does not have right child
135+
while node.parent != None and node.parent.right == node : # traverse to parent while Parent != None & node is right child of parent
136+
node = node.parent
137+
return node.parent
138+
else:
139+
return self.minimum(node.right) # return Minimum from right subtree
140+
141+
def predecessor(self, node):
142+
143+
if node.left == None:
144+
while node.parent != None and node.parent.left == node :
145+
node = node.parent
146+
return node.parent
147+
else:
148+
return self.maximum(node.left) # return Maximum from left subtree
149+
150+
if __name__ == "__main__":
151+
152+
T1 = BST()
153+
154+
# insert random 10 numbers in the tree
155+
for i in range(10):
156+
T1.insert(randint(1, 50))
157+
158+
print("Level-Order = ", T1.levelorder())
159+
print(" Pre-Order = ", T1.preorder())
160+
print(" Post-Order = ", T1.postorder())
161+
print(" In-Order = ", T1.inorder())
162+
163+
find = 10
164+
Found_Node = T1.search(find)
165+
if(Found_Node):
166+
print("Successor of", find, " = ", T1.successor(Found_Node))
167+
print("Predecessor of", find, " = ", T1.predecessor(Found_Node))
168+
print("\nValue Found, Parent = ", Found_Node.parent, "left = ", Found_Node.left, "right = ", Found_Node.right)
169+
else:
170+
print("\n", find, "not found in tree")
171+
172+
print("\nMaximum = ", T1.maximum())
173+
print("Minimum = ", T1.minimum())

0 commit comments

Comments
 (0)