-
Notifications
You must be signed in to change notification settings - Fork 13
/
BinaryTreeLL.py
201 lines (175 loc) · 6.84 KB
/
BinaryTreeLL.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
'''
Q- Implement a binary tree using Linked List data structure and perform all possible operations.
Use object oriented design to implement the logics taught.
'''
class TreeNode:
def __init__(self,data):
self.data = data
self.leftChild = None
self.rightChild = None
#creating tree - time and space is O(1)
newBT = TreeNode("Drinks")
leftChild = TreeNode("Hot")
tea = TreeNode('Tea')
coffee= TreeNode('Coffee')
leftChild.leftChild = tea
leftChild.rightChild = coffee
rightChild = TreeNode("Cold")
newBT.leftChild = leftChild
newBT.rightChild = rightChild
# create and call pre-order traversal function recursively
def preOrderTraversal(rootNode): #time and space is O(N)
if not rootNode:
return #--- O(1)
print(rootNode.data) #--- O(1)
preOrderTraversal(rootNode.leftChild) #--- O(n/2) (for each children there are two nodes)
preOrderTraversal(rootNode.rightChild) #--- O(n/2) (for each children there are two nodes)
#sanity check
preOrderTraversal(newBT)
def inOrderTraversal(rootNode): #time and space is O(N)
if not rootNode:
return #--- O(1)
inOrderTraversal(rootNode.leftChild) #--- O(n/2) (for each children there are two nodes)
print(rootNode.data) #--- O(1)
inOrderTraversal(rootNode.rightChild) #--- O(n/2) (for each children there are two nodes)
#sanity check
inOrderTraversal(newBT)
def postOrderTraversal(rootNode): #time and space is O(N)
if not rootNode:
return #--- O(1)
postOrderTraversal(rootNode.leftChild) #--- O(n/2) (for each children there are two nodes)
postOrderTraversal(rootNode.rightChild) #--- O(n/2) (for each children there are two nodes)
print(rootNode.data) #--- O(1)
#sanity check
postOrderTraversal(newBT)
'''
Note -
For level order traversal, we need to take the help of queue data structure
(since queue works as fifo), with linked list for implmenting l-o-t in binary tree.
For simplicity I will import the QueueLinkedList module which has already been coded by me earlier
while learning queue ds.
Trick - All other traversals in binary tree are performed via stack, except for level-order traversal which requires queue data structure.
'''
import QueueLinkedList as q
def levelOrderTraversal(rootNode): #time and space is O(N)
if not rootNode:
return
else:
customQueue = q.Queue()
customQueue.enqueue(rootNode)
while not(customQueue.isEmpty()):
root = customQueue.dequeue()
print(root.value.data)
if (root.value.leftChild is not None):
customQueue.enqueue(root.value.leftChild)
if (root.value.rightChild is not None):
customQueue.enqueue(root.value.rightChild)
levelOrderTraversal(newBT)
def searchBT(rootNode, nodeValue): #time and space is O(N)
if not rootNode:
return "The Binary Tree doesn't exist."
else:
customQueue = q.Queue()
customQueue.enqueue(rootNode)
while not(customQueue.isEmpty()):
root = customQueue.dequeue()
if root.value.data == nodeValue:
return "Successfully found the node!"
if (root.value.leftChild is not None):
customQueue.enqueue(root.value.leftChild)
if (root.value.rightChild is not None):
customQueue.enqueue(root.value.rightChild)
return "Value not found!"
print(searchBT(newBT, "cola"))
print(searchBT(newBT, "Tea"))
def insertNodeBT(rootNode, newNode): #time and space is O(N)
#base
if not rootNode:
rootNode = newNode
#use level-order traversal and insert newnode in left child of 1st vacant node of that level
else:
customQueue = q.Queue()
customQueue.enqueue(rootNode)
while not(customQueue.isEmpty()):
root = customQueue.dequeue()
if root.value.leftChild is not None:
customQueue.enqueue(root.value.leftChild)
else:
root.value.leftChild = newNode
return "Successfully inserted newnode!"
if root.value.rightChild is not None:
customQueue.enqueue(root.value.rightChild)
else:
root.value.rightChild = newNode
return "Successfully inserted newnode!"
newNode = TreeNode("Cola")
print(insertNodeBT(newBT, newNode))
#helper 1 for node deletion
def getDeepestNode(rootNode):
if not rootNode:
return
else:
customQueue = q.Queue()
customQueue.enqueue(rootNode)
while not(customQueue.isEmpty()):
root = customQueue.dequeue()
if (root.value.leftChild is not None):
customQueue.enqueue(root.value.leftChild)
if (root.value.rightChild is not None):
customQueue.enqueue(root.value.rightChild)
deepestNode = root.value
return deepestNode
deepestNode = getDeepestNode(newBT)
print(deepestNode.data)
#helper 2 for node deletion
def deleteDeepestNode(rootNode, dNode):
if not rootNode:
return
else:
customQueue = q.Queue()
customQueue.enqueue(rootNode)
while not(customQueue.isEmpty()):
root = customQueue.dequeue()
if root.value is dNode:
root.value = None
return
if root.value.rightChild:
if root.value.rightChild is dNode:
root.value.rightChild = None
return
else:
customQueue.enqueue(root.value.rightChild)
if root.value.leftChild:
if root.value.leftChild is dNode:
root.value.leftChild = None
return
else:
customQueue.enqueue(root.value.leftChild)
newNode = getDeepestNode(newBT)
deleteDeepestNode(newBT, newNode)
levelOrderTraversal(newBT)
def deleteNodeBT(rootNode, node): #time and space is O(N)
if not rootNode:
return "The Binary Tree doesn't exist."
else:
customQueue = q.Queue()
customQueue.enqueue(rootNode)
while not(customQueue.isEmpty()):
root = customQueue.dequeue()
if (root.value.data == node):
dNode = getDeepestNode(rootNode)
root.value.data = dNode.data
deleteDeepestNode(rootNode, dNode)
return "The node has been successfully deleted."
if (root.value.leftChild is not None):
customQueue.enqueue(root.value.leftChild)
if (root.value.rightChild is not None):
customQueue.enqueue(root.value.rightChild)
return "Failed to delete the node!"
deleteNodeBT(newBT, "Tea")
levelOrderTraversal(newBT)
def deleteBT(rootNode): #time is O(1) and space is O(1)
rootNode.data = None
rootNode.leftChild = None
rootNode.rightChild = None
return "The Binary Tree has been succesfully deleted."