8
8
* Heap Data structure
9
9
*
10
10
* Heaps can be used as an array. For any key at array position I,
11
- I left child is at ( 2i ), right child is at ( 2i+1 ) and parent is
12
- I at (int) (i / 2). Heap size is stored at index 0.
11
+ * left child is at ( 2i ), right child is at ( 2i+1 ) and parent is
12
+ * at (int) (i / 2). Heap size is stored at index 0.
13
13
*
14
14
* Basic operations of a heap are:
15
15
*
27
27
#include < stdint.h>
28
28
#include < stdbool.h>
29
29
#include < limits.h>
30
- #include " hash_code.h"
31
- #include " hash_table.h"
30
+ #include " generic.h"
32
31
33
32
namespace alg {
34
33
/* *
35
34
* define binary heap structure.
36
35
*/
37
36
template <typename T>
38
37
class Heap {
39
- private :
38
+ public :
40
39
/* *
41
40
* define key-value pair of heap struct.
42
41
*/
43
- struct KV {
42
+ struct elem {
44
43
public:
45
- int32_t key;
46
- T value ;
44
+ int key;
45
+ T data ;
47
46
};
48
- int32_t m_size; // current heap size.
49
- int32_t m_max; // max heap size.
50
- KV * m_kvs; // key value pairs.
51
-
52
- HashTable<T, int32_t > * m_idx; // key -> idx
53
47
48
+ private:
49
+ int m_size; // current heap size.
50
+ int m_max; // max heap size.
51
+ elem * m_heap; // key value pairs.
54
52
public:
55
53
Heap (int max) {
56
54
m_size = 0 ;
57
55
m_max = max+1 ;
58
- m_kvs = new KV[m_max];
59
- m_kvs[0 ].key = INT_MIN;
60
- m_idx = new HashTable<T, int32_t >(m_max);
56
+ m_heap = new elem[m_max];
61
57
};
62
58
63
59
~Heap () {
64
- delete [] m_kvs;
65
- delete m_idx;
60
+ delete [] m_heap;
66
61
};
67
62
68
63
private:
69
64
Heap (const Heap &);
70
65
Heap& operator =(const Heap&);
71
66
72
67
public:
73
-
74
- inline int min_key () const { return m_kvs[1 ].key ; };
75
- inline const T & min_value () const { return m_kvs[1 ].value ; };
76
-
77
68
// for loop through the kvs
78
- inline uint32_t count () const { return m_size; };
79
- inline const T & operator [] (uint32_t idx) const { return m_kvs[idx+1 ].value ; };
69
+ inline int count () const { return m_size; };
80
70
81
71
/* *
82
72
* insert a 'key'->'value' pair into the heap.
83
73
*/
84
- void insert (int key, const T & value ) {
74
+ void push (int key, const T & data ) {
85
75
// heap full, just return;
86
76
if (m_size == m_max) return ;
87
-
77
+ // put in the back, and try move upward the heap
78
+ m_heap[m_size].key = key;
79
+ m_heap[m_size].data = data;
80
+ up (m_size);
88
81
m_size++;
89
- m_kvs[m_size].key = key;
90
- m_kvs[m_size].value = value;
91
- (*m_idx)[value] = m_size;
92
-
93
- // Adjust its position
94
- int now = m_size;
95
- while (m_kvs[now/2 ].key > key) {
96
- m_kvs[now] = m_kvs[now/2 ];
97
- (*m_idx)[m_kvs[now/2 ].value ] = now;
98
- now /= 2 ;
99
- }
100
-
101
- m_kvs[now].key = key;
102
- m_kvs[now].value = value;
103
- (*m_idx)[value] = now;
104
82
}
105
83
106
84
/* *
@@ -113,84 +91,94 @@ namespace alg {
113
91
*/
114
92
inline void clear () { m_size = 0 ; }
115
93
94
+ bool contains (const T & data) {
95
+ for (int i=1 ;i<=m_size;i++) {
96
+ if (m_heap[i].data == data) return true ;
97
+ }
98
+ return false ;
99
+ }
100
+
116
101
/* *
117
- * contains test
102
+ * pop the min element
118
103
*/
119
- bool contains (const T & value) {
120
- for (int32_t i=1 ;i<=m_size;i++) {
121
- if (m_kvs[i].value == value) return true ;
122
- }
104
+ elem pop () {
105
+ int n = m_size-1 ;
106
+ swap (m_heap[0 ],m_heap[n]);
107
+ down (0 , n);
108
+ m_size--;
109
+ return m_heap[m_size];
110
+ }
123
111
112
+ /* *
113
+ * remove the given data
114
+ */
115
+ bool remove (T data) {
116
+ for (int i=0 ;i<m_size;i++) { // loop finding
117
+ if (m_heap[i].data == data) { // found
118
+ int n = m_size-1 ;
119
+ if (n != i) {
120
+ swap (m_heap[i], m_heap[n]);
121
+ down (i, m_size);
122
+ up (i);
123
+ }
124
+ m_size--;
125
+ return true ;
126
+ }
127
+ }
124
128
return false ;
125
129
}
126
130
127
131
/* *
128
- * delete the min element --> heap top.
132
+ * decrease key
133
+ * simpliy implemented as remove then push
129
134
*/
130
- void delete_min () {
131
- // heap[1] is the minimum key. So we remove heap[1].
132
- // Size of the heap is decreased. Now heap[1] has to be filled.
133
- // We put the last key in its place and see if it fits. If it
134
- // does not fit, take minimum key among both its children and
135
- // replaces parent with it. Again See if the last key fits
136
- // in that place.
137
- int32_t lastKey;
138
- T lastValue;
139
- int32_t child,now;
140
-
141
- // empty heap, just return
142
- if (m_size == 0 ) return ;
143
-
144
- lastKey = m_kvs[m_size].key ;
145
- lastValue = m_kvs[m_size].value ;
146
- m_size--;
135
+ void decrease_key (T data, int newkey) {
136
+ if (remove (data)) {
137
+ push (newkey, data);
138
+ }
139
+ }
147
140
148
- // now refers to the index at which we are now
149
- for (now = 1 ; now*2 <= m_size ;now = child) {
150
- // child is the index of the key which is minimum among
151
- // both the children, Indexes of children are i*2 and i*2 + 1
152
- child = now*2 ;
153
- // child!=heapSize beacuse heap[heapSize+1] does not exist,
154
- // which means it has only one child
155
- if (child != m_size && m_kvs[child+1 ].key < m_kvs[child].key ) {
156
- child++; // choose the minium one.
141
+ void up (int j) {
142
+ for (;;) {
143
+ int i = (j-1 )/2 ; // parent
144
+ if (i==j || !less (j,i)) { // j not smaller than i
145
+ break ;
157
146
}
158
- // To check if the last key fits or not it suffices to check
159
- // if the last key is less than the minimum key among both the children
160
- if (lastKey > m_kvs[child].key ) {
161
- m_kvs[now] = m_kvs[child];
162
- (*m_idx)[m_kvs[now].value ] = now; // record index
147
+ swap (m_heap[i], m_heap[j]);
148
+ j=i;
149
+ }
150
+ }
151
+
152
+ void down (int i, int n) {
153
+ for (;;) {
154
+ int j1 = 2 *i+1 ; // left child
155
+ if (j1 >=n || j1 < 0 ) { // j1 < 0 after int overflow
156
+ break ;
157
+ }
158
+
159
+ int j = j1;
160
+ int j2 = j1+1 ; // left child
161
+ if (j2 < n && !less (j1,j2)) {
162
+ j = j2; // choose the minium one.
163
163
}
164
- else { // It fits there
164
+
165
+ if (!less (j,i)) {
165
166
break ;
166
167
}
168
+ swap (m_heap[i], m_heap[j]);
169
+ i=j;
167
170
}
168
-
169
- m_kvs[now].key = lastKey;
170
- m_kvs[now].value = lastValue;
171
- (*m_idx)[lastValue] = now; // record index
172
171
}
173
172
174
- /* *
175
- * so called DECREASE KEY operation.
176
- * step 1. find the value
177
- * step 2. decrease the key to the newkey
178
- */
179
- void decrease_key (T value, int32_t newkey) {
180
- int32_t index = (*m_idx)[value];
181
- if (index > m_size || index == 0 ) return ; // value not found
182
- if (newkey >= m_kvs[index].key ) return ; // violate DECREASE meanning.
183
- T oldvalue = m_kvs[index].value ;
184
-
185
- int now = index;
186
- while (m_kvs[now/2 ].key > newkey) {
187
- m_kvs[now] = m_kvs[now/2 ];
188
- (*m_idx)[m_kvs[now].value ] = now; // record index
189
- now /= 2 ;
173
+ void print_heap () {
174
+ for (int i=0 ;i<m_size;i++) {
175
+ printf (" key:%d value:%d " , m_heap[i].key , m_heap[i].data );
190
176
}
177
+ printf (" \n " );
178
+ }
191
179
192
- m_kvs[now]. key = newkey;
193
- m_kvs[now]. value = oldvalue ;
180
+ bool less ( int i, int j) {
181
+ return m_heap[i]. key < m_heap[j]. key ;
194
182
}
195
183
};
196
184
}
0 commit comments