Skip to content

Commit bc43ff6

Browse files
author
Catislin
committed
refactoring:
1 parent 2ca8818 commit bc43ff6

File tree

2 files changed

+88
-47
lines changed

2 files changed

+88
-47
lines changed

source/binarytree.py

Lines changed: 88 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!python
2-
2+
from queue import LinkedQueue
33

44
class 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

289338
def test_binary_search_tree():

source/binarytree_test.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
#!python
22

3-
<<<<<<< HEAD
43
from binarytree import BinarySearchTree, BinaryTreeNode
5-
=======
6-
from binarysearchtree import BinarySearchTree, BinaryTreeNode
7-
>>>>>>> f0fa83432126a26df19a37b922cc61d27969f586
84
import unittest
95

106

@@ -160,8 +156,6 @@ def test_insert_with_7_items(self):
160156

161157
# This space intentionally left blank (please do not delete this comment)
162158

163-
<<<<<<< HEAD
164-
=======
165159
def test_items_in_order_with_3_strings(self):
166160
# Create a complete binary search tree of 3 strings in level-order
167161
items = ['B', 'A', 'C']
@@ -218,7 +212,5 @@ def test_items_level_order_with_7_numbers(self):
218212
# Ensure the level-order traversal of tree items is ordered correctly
219213
assert tree.items_level_order() == [4, 2, 6, 1, 3, 5, 7]
220214

221-
>>>>>>> f0fa83432126a26df19a37b922cc61d27969f586
222-
223215
if __name__ == '__main__':
224216
unittest.main()

0 commit comments

Comments
 (0)