11#!python
2-
2+ from queue import LinkedQueue
33
44class BinaryTreeNode (object ):
55
@@ -80,7 +80,7 @@ def search(self, item):
8080 TODO: Best case running time: ??? under what conditions?
8181 TODO: Worst case running time: ??? under what conditions?"""
8282 # Find a node with the given item, if any
83- node = self ._find_node (item )
83+ node = self ._find_node_recursive (item )
8484 # Return the node's data if found, or None
8585 if node :
8686 return node .data
@@ -118,7 +118,7 @@ def delete(self, item):
118118 if found :
119119 parent = self ._find_parent_node (item )
120120
121- def _find_node (self , item ):
121+ def _find_node_iterative (self , item ):
122122 """Return the node containing the given item in this binary search tree,
123123 or None if the given item is not found.
124124 TODO: Best case running time: ??? under what conditions?
@@ -142,7 +142,30 @@ def _find_node(self, item):
142142 # Not found
143143 return None
144144
145+ def _find_node_recursive (self , item , node = None ):
146+ # start with the root node
147+ if node is None :
148+ node = self .root
149+
150+ # check if this node has the item
151+ if node .data == item :
152+ return node
153+
154+ # recurse left IFF the item is smaller than the current
155+ # node's data and the current node has a left child
156+ elif item < node .data and node .left is not None :
157+ return self ._find_node_recursive (item , node .left )
158+ # recurse right IFF the item is larger than the current
159+ # node's data and the current node has a right child
160+ elif item > node .data and node .right is not None :
161+ return self ._find_node_recursive (item , node .right )
162+ else :
163+ return None
164+
145165 def _find_parent_node (self , item ):
166+ return self ._find_parent_node_iterative (item )
167+
168+ def _find_parent_node_iterative (self , item ):
146169 """Return the parent node of the node containing the given item
147170 (or the parent node of where the given item would be if inserted)
148171 in this tree, or None if this tree is empty or has only a root node.
@@ -170,14 +193,32 @@ def _find_parent_node(self, item):
170193 # Not found
171194 return parent
172195
196+ def _find_parent_node_recursive (self , item , parent = None ):
197+ if parent is None :
198+ if self .root .data == item :
199+ return None
200+ parent = self .root
201+
202+ if parent .left is not None :
203+ if item == parent .left .data :
204+ return parent
205+ if parent .right is not None :
206+ if item == parent .right .data :
207+ return parent
208+
209+ if item > parent .data :
210+ return self ._find_parent_node_recursive (item , parent = parent .right )
211+ elif item < parent .data :
212+ return self ._find_parent_node_recursive (item , parent = parent .left )
213+
173214 # This space intentionally left blank (please do not delete this comment)
174215
175216 def items_in_order (self ):
176217 """Return an in-order list of all items in this binary search tree."""
177218 items = []
178219 if not self .is_empty ():
179220 # Traverse tree in-order from root, appending each node's item
180- self ._traverse_in_order_recursive (self .root , items .append ):
221+ self ._traverse_in_order_recursive (self .root , items .append )
181222 # Return in-order list of all items in tree
182223 return items
183224
@@ -186,12 +227,14 @@ def _traverse_in_order_recursive(self, node, visit):
186227 Start at the given node and visit each node with the given function.
187228 TODO: Running time: ??? Why and under what conditions?
188229 TODO: Memory usage: ??? Why and under what conditions?"""
189- # TODO: Traverse left subtree, if it exists
190- ...
191- # TODO: Visit this node's data with given function
192- ...
193- # TODO: Traverse right subtree, if it exists
194- ...
230+ # Traverse left subtree, if it exists
231+ if node .left :
232+ self ._traverse_in_order_recursive (node .left , visit )
233+ # Visit this node's data with given function
234+ visit (node .data )
235+ # Traverse right subtree, if it exists
236+ if node .right :
237+ self ._traverse_in_order_recursive (node .right , visit )
195238
196239 def _traverse_in_order_iterative (self , node , visit ):
197240 """Traverse this binary tree with iterative in-order traversal (DFS).
@@ -205,7 +248,7 @@ def items_pre_order(self):
205248 items = []
206249 if not self .is_empty ():
207250 # Traverse tree pre-order from root, appending each node's item
208- self ._traverse_pre_order_recursive (self .root , items .append ):
251+ self ._traverse_pre_order_recursive (self .root , items .append )
209252 # Return pre-order list of all items in tree
210253 return items
211254
@@ -214,12 +257,14 @@ def _traverse_pre_order_recursive(self, node, visit):
214257 Start at the given node and visit each node with the given function.
215258 TODO: Running time: ??? Why and under what conditions?
216259 TODO: Memory usage: ??? Why and under what conditions?"""
217- # TODO: Visit this node's data with given function
218- ...
219- # TODO: Traverse left subtree, if it exists
220- ...
221- # TODO: Traverse right subtree, if it exists
222- ...
260+ # Visit this node's data with given function
261+ visit (node .data )
262+ # Traverse left subtree, if it exists
263+ if node .left :
264+ self ._traverse_pre_order_recursive (node .left , visit )
265+ # Traverse right subtree, if it exists
266+ if node .right :
267+ self ._traverse_pre_order_recursive (node .right , visit )
223268
224269 def _traverse_pre_order_iterative (self , node , visit ):
225270 """Traverse this binary tree with iterative pre-order traversal (DFS).
@@ -233,7 +278,7 @@ def items_post_order(self):
233278 items = []
234279 if not self .is_empty ():
235280 # Traverse tree post-order from root, appending each node's item
236- self ._traverse_post_order_recursive (self .root , items .append ):
281+ self ._traverse_post_order_recursive (self .root , items .append )
237282 # Return post-order list of all items in tree
238283 return items
239284
@@ -242,12 +287,14 @@ def _traverse_post_order_recursive(self, node, visit):
242287 Start at the given node and visit each node with the given function.
243288 TODO: Running time: ??? Why and under what conditions?
244289 TODO: Memory usage: ??? Why and under what conditions?"""
245- # TODO: Traverse left subtree, if it exists
246- ...
247- # TODO: Traverse right subtree, if it exists
248- ...
249- # TODO: Visit this node's data with given function
250- ...
290+ # Traverse left subtree, if it exists
291+ if node .left :
292+ self ._traverse_post_order_recursive (node .left , visit )
293+ # Traverse right subtree, if it exists
294+ if node .right :
295+ self ._traverse_post_order_recursive (node .right , visit )
296+ # Visit this node's data with given function
297+ visit (node .data )
251298
252299 def _traverse_post_order_iterative (self , node , visit ):
253300 """Traverse this binary tree with iterative post-order traversal (DFS).
@@ -261,7 +308,7 @@ def items_level_order(self):
261308 items = []
262309 if not self .is_empty ():
263310 # Traverse tree level-order from root, appending each node's item
264- self ._traverse_level_order_iterative (self .root , items .append ):
311+ self ._traverse_level_order_iterative (self .root , items .append )
265312 # Return level-order list of all items in tree
266313 return items
267314
@@ -270,20 +317,22 @@ def _traverse_level_order_iterative(self, start_node, visit):
270317 Start at the given node and visit each node with the given function.
271318 TODO: Running time: ??? Why and under what conditions?
272319 TODO: Memory usage: ??? Why and under what conditions?"""
273- # TODO: Create queue to store nodes not yet traversed in level-order
274- queue = ...
275- # TODO: Enqueue given starting node
276- ...
277- # TODO: Loop until queue is empty
278- while ...:
279- # TODO: Dequeue node at front of queue
280- node = ...
281- # TODO: Visit this node's data with given function
282- ...
283- # TODO: Enqueue this node's left child, if it exists
284- ...
285- # TODO: Enqueue this node's right child, if it exists
286- ...
320+ # Create queue to store nodes not yet traversed in level-order
321+ queue = LinkedQueue ()
322+ # Enqueue given starting node
323+ queue .enqueue (start_node )
324+ # Loop until queue is empty
325+ while not queue .is_empty ():
326+ # Dequeue node at front of queue
327+ node = queue .dequeue ()
328+ # Visit this node's data with given function
329+ visit (node .data )
330+ # Enqueue this node's left child, if it exists
331+ if node .left :
332+ queue .enqueue (node .left )
333+ # Enqueue this node's right child, if it exists
334+ if node .right :
335+ queue .enqueue (node .right )
287336
288337
289338def test_binary_search_tree ():
0 commit comments