Skip to content

Commit a6f0412

Browse files
committed
BST Implementation in Python
1 parent 3a26161 commit a6f0412

File tree

2 files changed

+287
-0
lines changed

2 files changed

+287
-0
lines changed

BinarySearchTree/BST.py

+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
2+
3+
'''
4+
Traversal of Binary Search Tree
5+
6+
Depth First Search
7+
- Preorder traversal
8+
- Inorder traversal
9+
- Postorder traversal
10+
11+
Breadth first search
12+
- Level order traversal
13+
'''
14+
15+
from QueueLinkedList import Queue
16+
17+
class BSTNode:
18+
def __init__(self, data) -> None:
19+
self.data = data
20+
self.leftChild = None
21+
self.rightChild = None
22+
23+
# Time: O(logn); Space: O(logn)
24+
# Insert a value in Binary Search Tree
25+
# We search for a empty space and insert a value that
26+
# satisfy the properties of Binary Search Tree
27+
def insertNode(rootNode, nodeValue):
28+
if rootNode.data is None:
29+
rootNode.data = nodeValue
30+
elif nodeValue <= rootNode.data:
31+
if rootNode.leftChild is None:
32+
rootNode.leftChild = BSTNode(nodeValue)
33+
else:
34+
insertNode(rootNode.leftChild, nodeValue)
35+
else:
36+
if rootNode.rightChild is None:
37+
rootNode.rightChild = BSTNode(nodeValue)
38+
else:
39+
insertNode(rootNode.rightChild, nodeValue)
40+
41+
return "The node has been successfully inserted"
42+
43+
# Traversal of Binary Search Tree
44+
45+
# PreOrder Traversal of BST
46+
# 1. Visit Root Node -> LeftSubTree -> RightSubTee
47+
# Time: O(n); Space: O(n)
48+
def preOrderTraversal(rootNode):
49+
if not rootNode:
50+
return
51+
print(rootNode.data, end='->')
52+
preOrderTraversal(rootNode.leftChild)
53+
preOrderTraversal(rootNode.rightChild)
54+
55+
# Inorder Traversal of BST
56+
# Vist LeftSubTree -> RootNode -> RightSubTree
57+
# Time: O(n); Space: O(n)
58+
def inOrderTraversal(rootNode):
59+
if not rootNode:
60+
return
61+
inOrderTraversal(rootNode.leftChild)
62+
print(rootNode.data, end='->')
63+
inOrderTraversal(rootNode.rightChild)
64+
65+
# PostOrder Traversal of BST
66+
# Visit LeftSubTree -> RightSubTree -> RootNode
67+
# Time: O(n); Space: O(n)
68+
def postOrderTraversal(rootNode):
69+
if not rootNode:
70+
return
71+
postOrderTraversal(rootNode.leftChild)
72+
postOrderTraversal(rootNode.rightChild)
73+
print(rootNode.data, end='->')
74+
75+
# Breadth Fist Search -> Level Order Traversal
76+
# Time: O(n); Space: O(n)
77+
def levelOrderTraversal(rootNode):
78+
if not rootNode:
79+
return
80+
else:
81+
customQueue = Queue()
82+
customQueue.enqueue(rootNode)
83+
while not(customQueue.isEmpty()):
84+
root = customQueue.dequeue()
85+
print(root.value.data, end='->')
86+
if root.value.leftChild is not None:
87+
customQueue.enqueue(root.value.leftChild)
88+
if root.value.rightChild is not None:
89+
customQueue.enqueue(root.value.rightChild)
90+
91+
# Search for a node in Bineary Search Tree
92+
# Time: O(logn); Space: O(logn)
93+
def searchNode(rootNode, nodeValue):
94+
if rootNode is None:
95+
return
96+
if rootNode.data == nodeValue:
97+
print("Value found!")
98+
elif nodeValue < rootNode.data:
99+
if rootNode.leftChild is not None:
100+
if rootNode.leftChild.data == nodeValue:
101+
print("Value found!")
102+
else:
103+
searchNode(rootNode.leftChild, nodeValue)
104+
else:
105+
print("Value not Found!")
106+
else:
107+
if rootNode.rightChild is not None:
108+
if rootNode.rightChild.data == nodeValue:
109+
print("Value Found!")
110+
else:
111+
searchNode(rootNode.rightChild, nodeValue)
112+
else:
113+
print("Value not Found!")
114+
115+
116+
def minValueNode(curNode):
117+
# minimum value lie in leftchild of current node
118+
current = curNode
119+
while (current.leftChild is not None):
120+
current = current.leftChild
121+
return current
122+
123+
# Delete a node from Binary Search Tree
124+
# Three cases:
125+
# Case1: The node to be deleted is a leaf
126+
# Case2: The node has one child
127+
# Case3: The node has two children
128+
# In this we have to find successor, which is minimum
129+
# value of rightSubTree. So, min Value is new parent node
130+
# where the value gets deleted.
131+
# Time: O(logn); Space: O(logn)
132+
def deleteNode(rootNode, nodeValue):
133+
if rootNode is None:
134+
return rootNode
135+
if nodeValue < rootNode.data:
136+
rootNode.leftChild = deleteNode(rootNode.leftChild, nodeValue)
137+
elif nodeValue > rootNode.data:
138+
rootNode.rightChild = deleteNode(rootNode.rightChild, nodeValue)
139+
else:
140+
if rootNode.leftChild is None:
141+
temp = rootNode.rightChild
142+
rootNode = None
143+
return temp
144+
if rootNode.rightChild is None:
145+
temp = rootNode.leftChild
146+
rootNode = None
147+
return temp
148+
149+
temp = minValueNode(rootNode.rightChild)
150+
rootNode.data = temp.data
151+
rootNode.rightChild= deleteNode(rootNode.rightChild, temp.data)
152+
return rootNode
153+
154+
# TIme: O(1); Space: O(1)
155+
def deleteEntireBST(rootNode):
156+
rootNode.data = None
157+
rootNode.leftChild = None
158+
rootNode.rightChild = None
159+
return "The BST has been successfully deleted"
160+
161+
162+
163+
164+
165+
newBST = BSTNode(None)
166+
print(insertNode(newBST, 70))
167+
print(insertNode(newBST, 50))
168+
print(insertNode(newBST, 90))
169+
print(insertNode(newBST, 30))
170+
print(insertNode(newBST, 60))
171+
print(insertNode(newBST, 80))
172+
print(insertNode(newBST, 100))
173+
print(insertNode(newBST, 20))
174+
print(insertNode(newBST, 40))
175+
176+
'''
177+
Binary Search Tree looks like as:
178+
Must Satisfy two properties:
179+
- In the left subtree the value of a node is less than or equal to its parent node’s value.
180+
- In the right subtree the value of a node is greater than its parent node’s values.
181+
182+
183+
70
184+
/ \
185+
/ \
186+
50 90
187+
/ \ / \
188+
30 60 80 100
189+
/ \
190+
20 40
191+
192+
'''
193+
194+
print("###")
195+
preOrderTraversal(newBST)
196+
print("\n##")
197+
inOrderTraversal(newBST)
198+
print("\n##")
199+
postOrderTraversal(newBST)
200+
print("\n##")
201+
levelOrderTraversal(newBST)
202+
print("\n##")
203+
searchNode(newBST, 60)
204+
searchNode(newBST, 10)
205+
deleteNode(newBST, 60)
206+
levelOrderTraversal(newBST)
207+
print("##")
208+
print(deleteEntireBST(newBST))
209+
levelOrderTraversal(newBST)

BinarySearchTree/QueueLinkedList.py

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
2+
3+
class Node:
4+
def __init__(self, value=None) -> None:
5+
self.value = value
6+
self.next = None
7+
8+
def __str__(self) -> str:
9+
return str(self.value)
10+
11+
class LinkedList:
12+
def __init__(self) -> None:
13+
self.head = None
14+
self.tail = None
15+
16+
def __iter__(self):
17+
node = self.head
18+
while node:
19+
yield node
20+
node = node.next
21+
22+
23+
class Queue:
24+
def __init__(self) -> None:
25+
self.linkedList = LinkedList()
26+
27+
def __str__(self) -> str:
28+
values = [str(x) for x in self.linkedList]
29+
return ' '.join(values)
30+
31+
def enqueue(self, value):
32+
newNode = Node(value)
33+
if self.linkedList.head == None:
34+
self.linkedList.head = newNode
35+
self.linkedList.tail = newNode
36+
else:
37+
self.linkedList.tail.next = newNode
38+
self.linkedList.tail = newNode
39+
40+
def isEmpty(self):
41+
if self.linkedList.head == None:
42+
return True
43+
else:
44+
return False
45+
46+
def dequeue(self):
47+
if self.isEmpty():
48+
return "Queue Underflow! No any element."
49+
else:
50+
tempNode = self.linkedList.head
51+
if self.linkedList.head == self.linkedList.tail:
52+
self.linkedList.head = None
53+
self.linkedList.tail = None
54+
else:
55+
self.linkedList.head = self.linkedList.head.next
56+
return tempNode
57+
58+
def peek(self):
59+
if self.isEmpty():
60+
return "Queue Underflow! No any element."
61+
else:
62+
return self.linkedList.head
63+
64+
65+
def deleteQueue(self):
66+
self.linkedList.head = None
67+
self.linkedList.tail = None
68+
69+
70+
custQueue = Queue()
71+
custQueue.enqueue(10)
72+
custQueue.enqueue(11)
73+
custQueue.enqueue(12)
74+
print(custQueue)
75+
print(custQueue.dequeue())
76+
print(custQueue)
77+
print(custQueue.peek())
78+
print(custQueue)

0 commit comments

Comments
 (0)