Skip to content

Commit 1dda7b8

Browse files
committed
BST remove working.
1 parent 24207be commit 1dda7b8

File tree

1 file changed

+83
-11
lines changed

1 file changed

+83
-11
lines changed

binary_tree.py

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,40 @@
1-
""" Binary Search Tree implemented with embedded lists. """
1+
""" Binary Search Tree implemented with embedded lists.
2+
3+
Node format: [value, left child, right child].
4+
Leaf nodes look like: [value, [], []].
5+
"""
26

37
__author__ = "Caleb Madrigal"
48
__date__ = "2015-02-25"
59

610

711
def node_value(node, new_value=None):
8-
if new_value:
12+
""" Set value: node_value(node, value); Get value: node_value(node). """
13+
14+
if new_value is not None:
915
node[0] = new_value
1016
return node[0]
1117

1218

1319
def left_child(node, new_node=None):
14-
if new_node:
20+
""" Set left child: left_child(node, new_left_child); Get left node: left_child(node). """
21+
22+
if new_node is not None:
1523
node[1] = new_node
1624
return node[1]
1725

1826

1927
def right_child(node, new_node=None):
20-
if new_node:
28+
""" Set right child: right_child(node, new_right_child); Get right node: right_child(node). """
29+
30+
if new_node is not None:
2131
node[2] = new_node
2232
return node[2]
2333

2434

2535
def add(tree, value):
36+
""" Adds value to tree and returns tree. """
37+
2638
if tree == []:
2739
tree = [value, [], []]
2840
elif node_value(tree) == None:
@@ -35,16 +47,72 @@ def add(tree, value):
3547
return tree
3648

3749

38-
def remove(tree, value):
39-
pass
40-
50+
def find_node(tree, value, parent=None, is_right_child=False):
51+
""" Returns (node, parent, is_right_child_of_parent) if found (parent is None if root).
52+
If not found, return (None, None, False). """
4153

42-
def contains(tree, value):
4354
if tree == []:
44-
return False
55+
return (None, parent, is_right_child)
4556
if node_value(tree) == value:
46-
return True
47-
return contains(left_child(tree), value) or contains(right_child(tree), value)
57+
return (tree, parent, is_right_child)
58+
elif value < node_value(tree):
59+
return find_node(left_child(tree), value, tree, False)
60+
else: # value > node_value(tree)
61+
return find_node(right_child(tree), value, tree, True)
62+
63+
64+
def contains(tree, value):
65+
""" Returns true if value in tree; False otherwise. """
66+
67+
return find_node(tree, value)[0] != None
68+
69+
70+
def find_min_node(tree, parent=None, is_right_child=False):
71+
if left_child(tree) == []:
72+
return (tree, parent, is_right_child)
73+
else:
74+
return find_min_node(left_child(tree), tree, False)
75+
76+
77+
def remove_node(node_to_remove, parent, is_right_child_of_parent):
78+
# If node not found, return None
79+
if not node_to_remove:
80+
return None
81+
82+
def set_parent_reference(new_reference):
83+
if parent:
84+
if is_right_child_of_parent:
85+
right_child(parent, new_reference)
86+
else:
87+
left_child(parent, new_reference)
88+
89+
# If the node to be removed has 2 children; Steps:
90+
# * Set the node_to_remove value to the min value in the right subtree
91+
# * call remove_node() on the item which was swapped with
92+
if left_child(node_to_remove) != [] and right_child(node_to_remove) != []:
93+
(right_child_min_node, rchild_min_node_parent, is_min_right_child) = \
94+
find_min_node(right_child(node_to_remove), node_to_remove, True)
95+
node_value(node_to_remove, node_value(right_child_min_node))
96+
remove_node(right_child_min_node, rchild_min_node_parent, is_min_right_child)
97+
98+
# If the node to be removed has just 1 child (the left child), set the parent reference
99+
# to the left child of the node to be removed
100+
elif left_child(node_to_remove) != []:
101+
set_parent_reference(left_child(node_to_remove))
102+
103+
# If the node to be removed has just 1 child (the right child), set the parent reference
104+
# to the right child of the node to be removed
105+
elif right_child(node_to_remove) != []:
106+
set_parent_reference(right_child(node_to_remove))
107+
108+
# The node has no children, so just remove it
109+
else:
110+
set_parent_reference([])
111+
112+
113+
def remove(tree, value):
114+
(node_to_remove, parent, is_right_child_of_parent) = find_node(tree, value)
115+
return remove_node(node_to_remove, parent, is_right_child_of_parent)
48116

49117

50118
def inorder(tree):
@@ -90,6 +158,7 @@ def print_tree(tree, indent=0):
90158
for i in [5, 3, 8, 5, 2, 10, 20, 15, 30, 0, 7]:
91159
tree = add(tree, i)
92160
print_tree(tree)
161+
print(tree)
93162
print("Is 5 in tree?", contains(tree, 5))
94163
print("Is 20 in tree?", contains(tree, 20))
95164
print("Is 100 in tree?", contains(tree, 100))
@@ -102,3 +171,6 @@ def print_tree(tree, indent=0):
102171
preorder_traverse(tree, lambda node: print(node, end=", "))
103172
print()
104173

174+
remove(tree, 8)
175+
print_tree(tree)
176+
print("Inorder:", inorder(tree))

0 commit comments

Comments
 (0)