|
1 | | -def swap(A, i, j): |
2 | | - tmp = A[i] |
3 | | - A[i] = A[j] |
4 | | - A[j] = tmp |
| 1 | +class PriorityQueue: |
| 2 | + def __init__(self, less): |
| 3 | + self.heap = Heap([], less, update_position) |
| 4 | + self.get_key_and_pos = {} |
5 | 5 |
|
6 | | -def less(x, y): |
7 | | - return x < y |
| 6 | + def __repr__(self): |
| 7 | + return repr(self.heap) |
8 | 8 |
|
9 | | -def less_key(x, y): |
10 | | - return x.key < y.key |
| 9 | + def push(self, key): |
| 10 | + kp = KeyWithPosition(key) |
| 11 | + self.get_key_and_pos[key] = kp |
| 12 | + self.heap.insert(kp) |
11 | 13 |
|
12 | | -def update_position(obj, pos): |
13 | | - obj.position = pos |
| 14 | + def pop(self): |
| 15 | + return self.heap.extract_max().key |
14 | 16 |
|
15 | | -def get_position(obj): |
16 | | - return obj.position |
| 17 | + def increase_key(self, key): |
| 18 | + obj = self.get_key_and_pos[key] |
| 19 | + heap_increase_key(self.heap, obj.position) |
17 | 20 |
|
18 | | -def ignore_update(obj, pos): |
19 | | - pass |
| 21 | + def empty(self): |
| 22 | + return self.heap.heap_size == 0 |
| 23 | + |
| 24 | +class KeyWithPosition: |
| 25 | + def __init__(self, k): |
| 26 | + self.key = k |
| 27 | + self.position = -1 |
| 28 | + |
| 29 | + def __repr__(self): |
| 30 | + return str(self.key) + '@' + repr(self.position) |
| 31 | + |
| 32 | +def update_position(key_with_pos, pos): |
| 33 | + key_with_pos.position = pos |
20 | 34 |
|
21 | 35 | class Heap: |
22 | | - def __init__(self, data, |
23 | | - less = less, |
24 | | - update = ignore_update): |
| 36 | + def __init__(self, data, less, update): |
25 | 37 | self.data = data |
26 | 38 | self.less = less |
27 | 39 | self.update = update |
@@ -64,6 +76,11 @@ def right(i): |
64 | 76 | def parent(i): |
65 | 77 | return (i-1) // 2 |
66 | 78 |
|
| 79 | +def swap(A, i, j): |
| 80 | + tmp = A[i] |
| 81 | + A[i] = A[j] |
| 82 | + A[j] = tmp |
| 83 | + |
67 | 84 | def heap_increase_key(H, i): |
68 | 85 | while i > 0 and H.less(H.data[parent(i)], H.data[i]): |
69 | 86 | swap(H.data, i, parent(i)) |
@@ -100,73 +117,48 @@ def heap_sort(H): |
100 | 117 | H.heap_size -= 1 |
101 | 118 | max_heapify(H, 0) |
102 | 119 |
|
103 | | -class PriorityQueue: |
104 | | - def __init__(self, less=less_key, update=update_position, get=get_position): |
105 | | - self.heap = Heap([], less=less, update=update) |
106 | | - self.get_position = get |
107 | | - self.get_object = {} |
108 | | - |
109 | | - def __repr__(self): |
110 | | - return repr(self.heap) |
111 | | - |
112 | | - def push(self, key): |
113 | | - o = Obj(key) |
114 | | - self.get_object[key] = o |
115 | | - self.heap.insert(o) |
116 | | - |
117 | | - def pop(self): |
118 | | - return self.heap.extract_max().key |
119 | | - |
120 | | - def increase_key(self, key): |
121 | | - obj = self.get_object[key] |
122 | | - heap_increase_key(self.heap, self.get_position(obj)) |
123 | | - |
124 | | - def empty(self): |
125 | | - return self.heap.heap_size == 0 |
126 | | - |
127 | | -class Obj: |
128 | | - def __init__(self, k): |
129 | | - self.key = k |
130 | | - self.position = -1 |
| 120 | +def less(x, y): |
| 121 | + return x < y |
131 | 122 |
|
132 | | - def __repr__(self): |
133 | | - return str(self.key) + '@' + repr(self.position) |
| 123 | +def ignore_update(obj, pos): |
| 124 | + pass |
134 | 125 |
|
135 | 126 | if __name__ == "__main__": |
136 | | - # test build and extract_max |
| 127 | + # test Heap build and extract_max |
137 | 128 | L = [4,3,5,1,2] |
138 | | - h = Heap(L) |
| 129 | + h = Heap(L, less, ignore_update) |
139 | 130 | for i in range(5, 0, -1): |
140 | 131 | assert h.extract_max() == i |
141 | 132 |
|
142 | | - # test insert |
| 133 | + # test Heap insert |
143 | 134 | L = [4,3,5,1,2] |
144 | 135 | for k in L: |
145 | 136 | h.insert(k) |
146 | 137 | for i in range(5, 0, -1): |
147 | 138 | assert h.extract_max() == i |
148 | 139 |
|
149 | | - # test sort |
| 140 | + # test heap_sort |
150 | 141 | L = [4,3,5,1,2] |
151 | | - heap_sort(Heap(L)) |
| 142 | + h = Heap(L, less, ignore_update) |
| 143 | + heap_sort(h) |
152 | 144 | for i in range(0, 5): |
153 | 145 | assert L[i] == i + 1 |
154 | 146 |
|
155 | | - # Test priority queue |
156 | | - # Q = PriorityQueue() |
157 | | - # for i in range(1, 6): |
158 | | - # Q.push(Obj(i)) |
159 | | - # for i in range(5, 0, -1): |
160 | | - # assert Q.pop().key == i |
161 | | - |
| 147 | + # test PriorityQeueue push and pop |
162 | 148 | L = {'a': 4, 'b': 3, 'c':5,'d':1,'e':2} |
163 | 149 | def less(x, y): |
164 | 150 | return L[x.key] < L[y.key] |
165 | 151 | Q = PriorityQueue(less) |
166 | 152 | for k, v in L.items(): |
167 | 153 | Q.push(k) |
168 | | - |
| 154 | + P = ['c', 'a', 'b', 'e', 'd'] |
| 155 | + for i in range(0, len(P)): |
| 156 | + assert Q.pop() == P[i] |
| 157 | + |
169 | 158 | # test increase_key |
| 159 | + Q = PriorityQueue(less) |
| 160 | + for k, v in L.items(): |
| 161 | + Q.push(k) |
170 | 162 | for k, v in L.items(): |
171 | 163 | L[k] = v + 2 |
172 | 164 | Q.increase_key(k) |
|
0 commit comments