-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathminheap.cpp
139 lines (120 loc) · 2.78 KB
/
minheap.cpp
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
#include "minheap.h"
MinHeap::MinHeap() {
array = new heapElem[2];
capacity = 1;
length = 0;
}
MinHeap::~MinHeap() {
delete[] array;
}
/*
If the capacity is not enought, double and
push the given element in the last position
after that increasyKey from this last position
it will positionate the given element in the appropiate
position
*/
void MinHeap::Push (const heapElem& e)
{
//In case there is not space for the next element to be allocated
if ( (length+1) >= capacity)
if (length == 1)
resize(4);
else
resize(capacity * 2);
array[++length] = e;
map[e.idx] = length;
increaseKey (length);
}
/* returns the root of the bheap */
const heapElem& MinHeap::Top () {
return array[1];
}
/* deletes the root of the bheap */
void MinHeap::Pop ()
{
array[1] = array[length];
length--;
decreaseKey (1);
}
/*
For the given element update, and than depends if
the new element is higher(key) or smaller increase or
decrease the key
*/
void MinHeap::Modify (const heapElem& e)
{
if (e.dist > array[ map[e.idx]].dist) {
array[ map[e.idx]] = e;
decreaseKey( map[e.idx]);
} else {
array[ map[e.idx]] = e;
increaseKey( map[e.idx]);
}
}
/*
For a given root positionate in the appropiate
position of the binary heap going to leaf nodes
*/
void MinHeap::decreaseKey (int i)
{
int largest = i;
int left = leftChild(i), right = rightChild(i);
if (left <= length && array[left].dist < array[largest].dist)
largest = left;
if (right <= length && array[right].dist < array[largest].dist)
largest = right;
if (largest != i) {
swap (i, largest);
decreaseKey (largest);
}
}
/*
For a given element positionate in the appropiate
position of the binary heap going to the top
*/
void MinHeap::increaseKey (int i)
{
if (i != 1 && array[i].dist < array[parent(i)].dist) {
swap (i, parent(i));
increaseKey (parent(i));
}
}
/*
Just create another array with the given size,
copy the original array to the new one,
and delete the original array.
*/
void MinHeap::resize (int _length)
{
heapElem* tmp = new heapElem[_length];
for (int i = 1; i <= length; i++) {
tmp[i] = array[i];
}
delete[] array;
array = tmp;
capacity = _length;
}
/*
The important point of this function is that
I also swap the value of the "map" array, As result
"map" array is always update since
the only operation which modify the heap is swap
*/
inline void MinHeap::swap(int i, int j) {
int map_aux = map [array[j].idx];
map[ array[j].idx] = map[ array[i].idx];
map[ array[i].idx] = map_aux;
heapElem& aux = array[j];
array[j] = array[i];
array[i] = aux;
}
inline int MinHeap::parent (int i) {
return ((int) i/2); /*A weird implementation of floor */
}
inline int MinHeap::leftChild (int i) {
return 2*i;
}
inline int MinHeap::rightChild (int i) {
return 2*i + 1;
}