-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpriority_queue.h
More file actions
145 lines (127 loc) · 3.75 KB
/
Copy pathpriority_queue.h
File metadata and controls
145 lines (127 loc) · 3.75 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
#ifndef __PRIORITY_QUEUE__
#define __PRIORITY_QUEUE__
#include <iostream>
#include <map>
#include <cassert>
using namespace std;
template<class T>
class MinHeap{
private:
T* A;
int size;
// mapping: node index to internal array index
map<int, int> node2heap;
// mapping: internal array index to node index
map<int, int> heap2node;
private:
// rebuild the heap
// Note: stat is the internal array index, this is also a private function
// this is a top-down approach
void min_heapify(int start){
// assume array implementation
int left = 2 * start;
int right = left + 1;
int smallest = start;
if(left <= this->size && get_key(A[left]) < get_key(A[start])){
smallest = left;
}else{
smallest = start;
}
if(right <= this->size && get_key(A[right]) < get_key(A[smallest])){
smallest = right;
}
if(smallest != start){
exchange(smallest, start);
min_heapify(smallest);
}
}
// exchange element
void exchange(int child, int parent){
assert (child > parent);
// get the node index of the current settings
int child_nodei = heap2node[child];
int parent_nodei = heap2node[parent];
T tmp = A[child];
A[child] = A[parent];
A[parent] = tmp;
// adjust the mapping
heap2node[child] = parent_nodei;
heap2node[parent] = child_nodei;
node2heap[parent_nodei] = child;
node2heap[child_nodei] = parent;
}
public:
MinHeap(int max_elements){
this->A = (T*)malloc((max_elements+1) * sizeof(T)); // this is 1-based
this->size = 0;
this->A[0] = NULL;
}
T get_min(){
return A[1];
}
int get_size(){
return this->size;
}
T extract_min(){
if(this->size <= 0){
cout << "Error: No elements in heap." << endl;
return NULL;
}
T min_ele = A[1];
A[1] = A[this->size];
// delete current mapping
int nodei = heap2node[this->size];
node2heap.erase(nodei);
heap2node.erase(this->size);
heap2node[1] = nodei;
node2heap[nodei] = 1;
this->size --;
// adjsut the heap
min_heapify(1);
return min_ele;
}
/*
Params:
nodei: the node index
key: the new key
*/
void decrease_key(int nodei, int key){
// first get the index of internal heap array
int i = node2heap[nodei];
if(key > get_key(A[i])){
cout << "Current key is even smaller than the given key." << endl;
}
set_key(A[i], key);
int parent = i / 2;
while(i > 1 && get_key(A[parent]) > get_key(A[i])){
// swap A[i/2] and A[i]
//cout << "Exchanging between " << i << " and " << i/2 << endl;
exchange(i, parent);
i = parent;
parent = i / 2;
}
}
// e: the element, nodei: node index
void insert(T e, int nodei){
this->size ++;
A[this->size] = e;
int i = this->size;
// init the mapping
heap2node[this->size] = nodei;
node2heap[nodei] = this->size;
// similar to decrease_key
while(i > 1 && get_key(A[i/2]) > get_key(A[i])){
// swap A[i/2] and A[i]
exchange(i, i/2);
}
}
void print_node_heap_mapping(){
cout << "Print node and heap mapping:" << endl;
int i;
for(i=1; i<=this->size; i++){
cout << "Heap index: " << i << " Node index: " << heap2node[i];
cout << "\tNode index: " << heap2node[i] << " Heap index: " << node2heap[heap2node[i]] << endl;
}
}
};
#endif