Skip to content

Commit 91bef85

Browse files
author
Unknown
committed
sorting and binary tree delete
1 parent bc43ff6 commit 91bef85

File tree

4 files changed

+142
-4
lines changed

4 files changed

+142
-4
lines changed

source/TreeMap.py

Whitespace-only changes.

source/binarytree.py

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ def height(self):
2828
downward path from this node to a descendant leaf node).
2929
Best case running time: O(1) if tree is empty
3030
Worst case running time: O(n) if the tree is on one long branch"""
31-
right_height, left_height = 0
31+
right_height, left_height = 0, 0
3232
# base case
33-
if self.is_leaf:
33+
if self.is_leaf():
3434
return 0
3535
if self.right:
3636
right_height = self.right.height() # use ternary
@@ -64,6 +64,9 @@ def height(self):
6464
# Check if root node has a value and if so calculate its height
6565
if self.root:
6666
return self.root.height()
67+
else:
68+
return 0
69+
6770

6871
def contains(self, item):
6972
"""Return True if this binary search tree contains the given item.
@@ -113,11 +116,75 @@ def insert(self, item):
113116
# Increase the tree size
114117
self.size += 1
115118

119+
# swaps two nodes
120+
def swap(self, a, b):
121+
# swap data
122+
a_data = a.data
123+
b_data = b.data
124+
a.data = b_data
125+
b.data = a_data
126+
# swap child pointers
127+
a_left = a.left
128+
a_right = a.right
129+
a.left = b.left
130+
a.right = b.right
131+
b.left = a_left
132+
b.right = a_right
133+
134+
def _find_successor(self, node):
135+
# find the leftmost node in the right subtree
136+
if node.right:
137+
current = node.right
138+
while current.left:
139+
current = current.left
140+
return current
141+
142+
def _find_predecessor(self, node):
143+
if node.left:
144+
current = node.left
145+
while current.right:
146+
current = current.right
147+
return current.right
148+
116149
def delete(self, item):
117-
found = self.search(item)
118-
if found:
150+
found = self._find_node_recursive(item)
151+
if found is not None: # only attempt to delete if the element is present
119152
parent = self._find_parent_node(item)
120153

154+
# Case 1: node to be removed has no children
155+
if not found.left and not found.right:
156+
if self.root is found:
157+
self.root = None
158+
else:
159+
if parent.right is found:
160+
parent.right = None
161+
elif parent.left is found:
162+
parent.left = None
163+
# Case 2: node to be removed has one child
164+
if found.right and not found.left: # node to remove has only right child
165+
if found is self.root: # node to remove is root
166+
self.root = found.right
167+
else:
168+
if parent.right is found: # node to remove is right child
169+
parent.right = found.right
170+
if parent.left is found: # node to remove is left child
171+
parent.left = found.right
172+
if found.left and not found.right: # node to remove has only left child
173+
if found is self.root: # node to remove is root
174+
self.root = found.left
175+
else:
176+
if parent.right is found: # node to remove is right child
177+
parent.right = found.left
178+
if parent.left is found: # node to remove is left child
179+
parent.left = found.left
180+
181+
# Case 3: node to be removed has three children
182+
# First find the successor (or predecessor) of the this node.
183+
# Delete the successor (or predecessor) from the tree.
184+
# Replace the node to be deleted with the successor (or predecessor)
185+
186+
187+
121188
def _find_node_iterative(self, item):
122189
"""Return the node containing the given item in this binary search tree,
123190
or None if the given item is not found.

source/binarytree_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ def test_init_with_list_of_tuples(self):
8080
assert tree.size == 3
8181
assert tree.is_empty() is False
8282

83+
def test_height(self):
84+
tree = BinarySearchTree([2, 1, 3])
85+
assert tree.height() == 1
86+
tree.insert(4)
87+
assert tree.height() == 2
88+
8389
def test_size(self):
8490
tree = BinarySearchTree()
8591
assert tree.size == 0
@@ -90,6 +96,14 @@ def test_size(self):
9096
tree.insert('C')
9197
assert tree.size == 3
9298

99+
def test_delete(self):
100+
tree = BinarySearchTree([2, 4])
101+
assert tree.height() == 1
102+
tree.delete(4)
103+
assert tree.height() == 0
104+
tree.delete(2)
105+
assert tree.height() == 0
106+
93107
def test_search_with_3_items(self):
94108
# Create a complete binary search tree of 3 items in level-order
95109
items = [2, 1, 3]

source/selection.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
def selection_sort(to_sort):
3+
min_index = 0
4+
# go through each element in the list
5+
for i in range(len(to_sort)):
6+
# go through the part that hasn't been sorted yet
7+
min_so_far = to_sort[i]
8+
for j in range(i, len(to_sort)):
9+
# find the min element in the unsorted part of the list
10+
if list_to_sort[j] < min_so_far:
11+
min_so_far = to_sort[j]
12+
min_index = j
13+
# swap the min element found and the current element of
14+
# the unsorted list
15+
temp = to_sort[i]
16+
to_sort[i] = min_so_far
17+
to_sort[min_index] = temp
18+
19+
def bubble_sort(to_sort):
20+
# we want to iterate until the list is sorted
21+
# that is, until we iterate through and do not encounter
22+
# a pair of elements that are out of order
23+
not_sorted = True
24+
while not_sorted:
25+
not_sorted = False
26+
# iterate through the unsorted part of the list
27+
for i in range(len(to_sort) - 2):
28+
# if we encounter two elements that are out of order
29+
# that is, an element is smaller than the one that
30+
# precedes it, then swap those elements and record that
31+
# the list is not yet sorted, so that we iterate again
32+
if to_sort[i + 1] < to_sort[i]:
33+
to_sort[i + 1], to_sort[i] = to_sort[i], to_sort[i + 1]
34+
not_sorted = True
35+
36+
def insertion_sort(to_sort):
37+
# iterate through each element
38+
for i, item in enumerate(to_sort):
39+
# store the current element
40+
current_item = to_sort[i]
41+
# find the index the current item belongs at by looping back through
42+
for j in range(i, 0, -1):
43+
# if the element to the left is greater than the current element,
44+
# then swap the current element with that one (move it left)
45+
if to_sort[j] > current_item:
46+
temp = to_sort[j]
47+
to_sort[j] = current_item
48+
to_sort[j + 1] = temp
49+
50+
51+
if __name__ == '__main__':
52+
numbers = [4, 8, 9, 10, -72, 21, 33, 99, 33]
53+
insertion_sort(numbers)
54+
print(numbers)
55+
letters = ['a', 'p', 'z', 'c', 'g', 'j', 'j', 'e']
56+
insertion_sort(letters)
57+
print(letters)

0 commit comments

Comments
 (0)