Skip to content

Commit c2f9c4e

Browse files
committed
Got pop (and heap_down) working.
1 parent c17c103 commit c2f9c4e

File tree

2 files changed

+62
-14
lines changed

2 files changed

+62
-14
lines changed

heap.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,47 @@ def _parent(self, index):
4141
def _is_root(self, index):
4242
return index == 0
4343

44+
def _swap(self, i1, i2):
45+
self.data[i1], self.data[i2] = self.data[i2], self.data[i1]
46+
4447
def build_heap(self, initial_data):
4548
for i in initial_data:
4649
self.data.append(i)
4750

4851
def heap_up(self, index):
49-
# Return if we are at the root
52+
# If we are at the root, return - we are done
5053
if self._is_root(index):
5154
return
5255

53-
# Else, compare the current node with the parent node, and:
54-
# * this node > parent node (for max heap)
55-
# * this node < parent node (for min heap)
56-
# Then swap and recursively do the same, but at the parent index (which is now
57-
# where the node in question resides).
56+
# Else, compare the current node with the parent node, and if this node should be higher
57+
# then the parent node, then swap and recursively call on the parent index
5858
parent_index = self._parent(index)
5959
if self.comparator(self.data[index], self.data[parent_index]):
60-
self.data[index], self.data[parent_index] = self.data[parent_index], self.data[index]
60+
self._swap(index, parent_index)
6161
self.heap_up(parent_index)
62-
else:
63-
return
6462

6563
def heap_down(self, index):
66-
pass
64+
left_index = self._left_child(index)
65+
right_index = self._right_child(index)
66+
left = self.data[left_index]
67+
right = self.data[right_index]
68+
69+
# Find the largest child
70+
largest_child = left
71+
largest_child_index = left_index
72+
if left is not None and right is not None:
73+
if self.comparator(right, left):
74+
largest_child = right
75+
largest_child_index = right_index
76+
elif right is not None:
77+
largest_child = right
78+
largest_child_index = right_index
79+
80+
# If the largest child is not None and is higher priority than the current, then swap
81+
# and recursively call on on the child index
82+
if largest_child is not None and self.comparator(largest_child, self.data[index]):
83+
self._swap(index, largest_child_index)
84+
self.heap_down(largest_child_index)
6785

6886
def push(self, item):
6987
insert_index = self.size # Insert at the end
@@ -78,13 +96,19 @@ def peek(self):
7896
return self.data[0]
7997

8098
def pop(self):
99+
if len(self.data) < 1 or self.data[0] is None:
100+
return None
101+
81102
# Take item from the root
82103
item = self.data[0]
83104

84105
# Move the bottom-most, right-most item to the root
85-
self.data[0] = self.data[self.size]
86-
del self.data[self.size]
106+
self.data[0] = self.data[self.size-1]
107+
self.data[self.size-1] = None
87108
self.size -= 1
109+
110+
self.heap_down(0)
111+
88112
return item
89113

90114
def __repr__(self):

test/test_heap.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
class HeapTest(unittest.TestCase):
1010

11-
def testMaxPushHeap(self):
11+
def testMaxHeapPushPop(self):
12+
# Test push
1213
h = heap.Heap()
1314
h.push(5).push(3).push(9).push(1)
1415
self.assertEqual(str(h), "[9, 3, 5, 1]")
@@ -25,7 +26,17 @@ def testMaxPushHeap(self):
2526
h.push(21)
2627
self.assertEqual(str(h), "[21, 20, 7, 9, 3, 2, 5, 1]")
2728

28-
def testMinPushHeap(self):
29+
# Test peek
30+
self.assertEqual(h.peek(), 21)
31+
32+
# Test pop
33+
self.assertEqual(h.pop(), 21)
34+
self.assertEqual(h.pop(), 20)
35+
self.assertEqual(h.pop(), 9)
36+
self.assertEqual(h.pop(), 7)
37+
38+
def testMinHeapPushPop(self):
39+
# Test Push
2940
h = heap.Heap([], heap.HeapType.minheap)
3041
h.push(5)
3142
self.assertEqual(str(h), "[5]")
@@ -42,6 +53,19 @@ def testMinPushHeap(self):
4253
h.push(-1)
4354
self.assertEqual(str(h), "[-1, 3, 5, 7, 4]")
4455

56+
# Test peek
57+
self.assertEqual(h.peek(), -1)
58+
59+
# Test pop
60+
self.assertEqual(h.pop(), -1)
61+
self.assertEqual(h.pop(), 3)
62+
self.assertEqual(h.pop(), 4)
63+
self.assertEqual(h.pop(), 5)
64+
h.push(-10)
65+
self.assertEqual(h.pop(), -10)
66+
67+
def testMaxHeapBuild(self):
68+
pass
4569
#data = [6, 1, 4, 9, 8, 2, 3]
4670
#h = heap.Heap(data, heap.HeapType.maxheap)
4771
#self.assertEqual(h.pop(), 9)

0 commit comments

Comments
 (0)