-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap.h
executable file
·211 lines (179 loc) · 6.09 KB
/
heap.h
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#ifndef HEAP_H
#define HEAP_H
#include <vector>
#include <functional>
#include <utility>
#include <algorithm>
#include <stdexcept>
#include <unordered_map>
#include <iostream>
template <
typename T,
typename TComparator = std::equal_to<T>,
typename PComparator = std::less<double>,
typename Hasher = std::hash<T> >
class Heap
{
public:
/// Constructs an m-ary heap. M should be >= 2
Heap(int m = 2,
const PComparator& c = PComparator(),
const Hasher& hash = Hasher(),
const TComparator& tcomp = TComparator() );
/// Destructor as needed
~Heap();
/// Adds an item with the provided priority
void push(double pri, const T& item);
/// returns the element at the top of the heap
/// max (if max-heap) or min (if min-heap)
T const & top() const;
/// Removes the top element
void pop();
/// returns true if the heap is empty
bool empty() const;
/// decreaseKey reduces the current priority of
/// item to newpri, moving it up in the heap
/// as appropriate.
void decreaseKey(double newpri, const T& item);
private:
/// Add whatever helper functions you need below
void heapify(int loc);
void trickleUp(int loc);
void swap(int parent, int loc);
/// delet this shit later
void printPriority();
void printInside();
// These should be all the data members you need.
std::vector< std::pair<double, T> > store_;
int m_;
PComparator c_;
std::unordered_map<T, size_t, Hasher, TComparator> keyToLocation_;
};
// Complete
template <typename T, typename TComparator, typename PComparator, typename Hasher >
Heap<T,TComparator,PComparator,Hasher>::Heap(
int m,
const PComparator& c,
const Hasher& hash,
const TComparator& tcomp ) :
store_(),
m_(m),
c_(c),
keyToLocation_(100, hash, tcomp)
{
}
// Complete
template <typename T, typename TComparator, typename PComparator, typename Hasher >
Heap<T,TComparator,PComparator,Hasher>::~Heap()
{
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::push(double priority, const T& item)
{
// You complete.
//pushes on both the store_ which holds the heap implementaitnos
//and also onto the unordered map
store_.push_back(std::pair<double, T>(priority, item));
keyToLocation_.insert(std::pair<T, size_t>(item, store_.size() - 1));
trickleUp(store_.size() - 1);
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::decreaseKey(double priority, const T& item)
{
// You complete
if(keyToLocation_.find(item) == keyToLocation_.end()){
return;
}
store_[keyToLocation_[item]].first = priority;
//either one of the two will go thru and fix shit depending
//on max or min heap
trickleUp(keyToLocation_[item]);
heapify(keyToLocation_[item]);
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
T const & Heap<T,TComparator,PComparator,Hasher>::top() const
{
// Here we use exceptions to handle the case of trying
// to access the top element of an empty heap
if(empty()) {
throw std::logic_error("can't top an empty heap");
}
// You complete
return store_[0].second;
}
/// Removes the top element
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::pop()
{
if(empty()) {
throw std::logic_error("can't pop an empty heap");
}
// You complete
//according to the slides, stick last element in front
//and remove last element from back
//then trickle down
//also removs from unordered map
keyToLocation_.erase(store_[0].second);
store_[0] = store_.back();
store_.pop_back();
heapify(0);
}
/// returns true if the heap is empty
template <typename T, typename TComparator, typename PComparator, typename Hasher >
bool Heap<T,TComparator,PComparator,Hasher>::empty() const
{
return store_.empty();
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::heapify(int i) {
if((m_ * i) + 1 < (int)store_.size()){
int smallest = (m_ * i) + 1;
int current = (m_ * i) + 2;
//loop thru all the children that exist
//if one should go ahead of parent,
//swap em and heapify recurse
while(current < (int)store_.size() and current <= (m_ * i) + m_){
if(c_(store_[current].first, store_[smallest].first)){
smallest = current;
}
current++;
}
if(c_(store_[smallest].first, store_[i].first)){
swap(i, smallest);
heapify(smallest);
}
}
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::trickleUp(int loc) {
int parent = (loc - 1) / m_;
while (parent >= 0 && c_(store_[loc].first, store_[parent].first)) {
swap(parent, loc);
loc = parent;
parent = (loc - 1) / m_;
}
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::swap(int parent, int loc) {
//when swaps, also swap the location referenced in the map
keyToLocation_[store_[parent].second] = loc;
keyToLocation_[store_[loc].second] = parent;
std::pair<double, T> temp = store_[parent];
store_[parent] = store_[loc];
store_[loc] = temp;
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::printPriority() {
for(size_t i = 0; i < store_.size(); i++){
std::cout << store_[i].first;
}
std::cout << std::endl;
}
template <typename T, typename TComparator, typename PComparator, typename Hasher >
void Heap<T,TComparator,PComparator,Hasher>::printInside() {
for(size_t i = 0; i < store_.size(); i++){
std::cout << store_[i].second;
}
std::cout << std::endl;
}
#endif