88 * Heap Data structure
99 *
1010 * 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.
1313 *
1414 * Basic operations of a heap are:
1515 *
2727#include < stdint.h>
2828#include < stdbool.h>
2929#include < limits.h>
30- #include " hash_code.h"
31- #include " hash_table.h"
30+ #include " generic.h"
3231
3332namespace alg {
3433/* *
3534 * define binary heap structure.
3635 */
3736template <typename T>
3837class Heap {
39- private :
38+ public :
4039/* *
4140 * define key-value pair of heap struct.
4241 */
43- struct KV {
42+ struct elem {
4443public:
45- int32_t key;
46- T value ;
44+ int key;
45+ T data ;
4746};
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
5347
48+ private:
49+ int m_size;// current heap size.
50+ int m_max;// max heap size.
51+ elem * m_heap;// key value pairs.
5452public:
5553Heap (int max) {
5654m_size = 0 ;
5755m_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];
6157};
6258
6359~Heap () {
64- delete [] m_kvs;
65- delete m_idx;
60+ delete [] m_heap;
6661};
6762
6863private:
6964Heap (const Heap &);
7065Heap& operator =(const Heap&);
7166
7267public:
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-
7768// 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; };
8070
8171/* *
8272 * insert a 'key'->'value' pair into the heap.
8373 */
84- void insert (int key, const T & value ) {
74+ void push (int key, const T & data ) {
8575// heap full, just return;
8676if (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);
8881m_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;
10482}
10583
10684/* *
@@ -113,84 +91,94 @@ namespace alg {
11391 */
11492inline void clear () { m_size = 0 ; }
11593
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+
116101/* *
117- * contains test
102+ * pop the min element
118103 */
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+ }
123111
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+ }
124128return false ;
125129}
126130
127131/* *
128- * delete the min element --> heap top.
132+ * decrease key
133+ * simpliy implemented as remove then push
129134 */
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+ }
147140
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 ;
157146}
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.
163163}
164- else { // It fits there
164+
165+ if (!less (j,i)) {
165166break ;
166167}
168+ swap (m_heap[i], m_heap[j]);
169+ i=j;
167170}
168-
169- m_kvs[now].key = lastKey;
170- m_kvs[now].value = lastValue;
171- (*m_idx)[lastValue] = now;// record index
172171}
173172
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 );
190176}
177+ printf (" \n " );
178+ }
191179
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 ;
194182}
195183};
196184}
0 commit comments