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
711def 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
1319def 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
1927def 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
2535def 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
50118def 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