-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap.py
133 lines (99 loc) · 2.88 KB
/
heap.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import heapq
class Heap(object):
def __init__(self):
self.heap = []
def size(self):
return len(self.heap)
def peek(self):
raise NotImplementedError()
def pop(self, item):
raise NotImplementedError()
def push(self):
raise NotImplementedError()
def replace(self):
raise NotImplementedError()
class MaxHeap(Heap):
"""
to leverage the heapq module, I will store -item for every item
so peek, returning -item being the smallest will be the largest item
"""
def peek(self):
return -self.heap[0]
def pop(self):
return -heapq.heappop(self.heap)
def push(self, item):
heapq.heappush(self.heap, -item)
class MinHeap(Heap):
def peek(self):
return self.heap[0]
def pop(self):
return heapq.heappop(self.heap)
def push(self, item):
heapq.heappush(self.heap, item)
class FixedSizeMixin(object):
def __init__(self, fixed_size):
super(FixedSizeMixin, self).__init__()
self.fixed_size = fixed_size
def push(self, item):
if self.size() == self.fixed_size:
heapq.heappushpop(self.heap, item)
else:
heapq.heappush(self.heap, item)
class FixedSizeMinHeap(FixedSizeMixin, MinHeap):
pass
class FixedSizeMaxHeap(FixedSizeMixin, MaxHeap):
def push(self, item):
super(FixedSizeMaxHeap, self).push(-item)
def test_min_heap():
min_heap = MinHeap()
min_heap.push(2)
min_heap.push(3)
min_heap.push(1)
assert min_heap.size() == 3
assert min_heap.peek() == 1
assert min_heap.pop() == 1
assert min_heap.pop() == 2
assert min_heap.pop() == 3
def test_max_heap():
max_heap = MaxHeap()
max_heap.push(2)
max_heap.push(3)
max_heap.push(1)
assert max_heap.size() == 3
assert max_heap.peek() == 3
assert max_heap.pop() == 3
assert max_heap.pop() == 2
assert max_heap.pop() == 1
def test_fixed_min_heap():
min_heap = FixedSizeMinHeap(3)
min_heap.push(2)
min_heap.push(3)
min_heap.push(0)
# heap: 0, 2 and 3 => at capacity
assert min_heap.size() == 3
min_heap.push(1)
# 0 < 1 so get rid of 0 and keep 1: 1, 2 and 3
assert min_heap.size() == 3
assert min_heap.peek() == 1
assert min_heap.pop() == 1
assert min_heap.pop() == 2
assert min_heap.pop() == 3
def test_fixed_max_heap():
max_heap = FixedSizeMaxHeap(3)
max_heap.push(2)
max_heap.push(3)
max_heap.push(0)
# heap: 0, 2 and 3 => at capacity
assert max_heap.size() == 3
max_heap.push(1)
# 1 < 3 so get rid of 3 and keep 1: 0, 1 and 2
assert max_heap.size() == 3
assert max_heap.peek() == 2
assert max_heap.pop() == 2
assert max_heap.pop() == 1
assert max_heap.pop() == 0
if __name__ == '__main__':
test_min_heap()
test_max_heap()
test_fixed_min_heap()
test_fixed_max_heap()