00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "minpq.h"
00010 #include "utils.h"
00011
00012 #include <limits.h>
00013
00014
00015
00016 void restore_minpq_order( struct pq_node*, int, int );
00017 void decrease_pq_node_key( struct pq_node*, int, int );
00018
00019
00020
00021
00022
00023 static inline int parent( int i )
00024 {
00025 return ( i - 1 ) / 2;
00026 }
00027
00028
00029
00030 static inline int right( int i )
00031 {
00032 return 2 * i + 2;
00033 }
00034
00035
00036
00037 static inline int left( int i )
00038 {
00039 return 2 * i + 1;
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049 struct min_pq* minpq_init()
00050 {
00051 struct min_pq* min_pq;
00052
00053 min_pq = (struct min_pq *) malloc( sizeof( struct min_pq ) );
00054 min_pq->pq_array = (struct pq_node *) calloc( MINPQ_INIT_NALLOCD, sizeof( struct pq_node ) );
00055 min_pq->nallocd = MINPQ_INIT_NALLOCD;
00056 min_pq->n = 0;
00057
00058 return min_pq;
00059 }
00060
00061
00062
00072 int minpq_insert( struct min_pq* min_pq, void* data, int key )
00073 {
00074 int n = min_pq->n;
00075
00076
00077 if( min_pq->nallocd == n )
00078 {
00079 min_pq->nallocd = array_double( (void **) &min_pq->pq_array, min_pq->nallocd,
00080 sizeof( struct pq_node ) );
00081 if( ! min_pq->nallocd )
00082 {
00083 fprintf( stderr, "Warning: unable to allocate memory, %s, line %d\n",
00084 __FILE__, __LINE__ );
00085 return 1;
00086 }
00087 }
00088
00089 min_pq->pq_array[n].data = data;
00090 min_pq->pq_array[n].key = INT_MAX;
00091 decrease_pq_node_key( min_pq->pq_array, min_pq->n, key );
00092 min_pq->n++;
00093
00094 return 0;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 void* minpq_get_min( struct min_pq* min_pq )
00109 {
00110 if( min_pq->n < 1 )
00111 {
00112 fprintf( stderr, "Warning: PQ empty, %s line %d\n", __FILE__, __LINE__ );
00113 return NULL;
00114 }
00115 return min_pq->pq_array[0].data;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void* minpq_extract_min( struct min_pq* min_pq )
00130 {
00131 void* data;
00132
00133 if( min_pq->n < 1 )
00134 {
00135 fprintf( stderr, "Warning: PQ empty, %s line %d\n", __FILE__, __LINE__ );
00136 return NULL;
00137 }
00138 data = min_pq->pq_array[0].data;
00139 min_pq->n--;
00140 min_pq->pq_array[0] = min_pq->pq_array[min_pq->n];
00141 restore_minpq_order( min_pq->pq_array, 0, min_pq->n );
00142
00143 return data;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 void minpq_release( struct min_pq** min_pq )
00153 {
00154 if( ! min_pq )
00155 {
00156 fprintf( stderr, "Warning: NULL pointer error, %s line %d\n", __FILE__,
00157 __LINE__ );
00158 return;
00159 }
00160 if( *min_pq && (*min_pq)->pq_array )
00161 {
00162 free( (*min_pq)->pq_array );
00163 free( *min_pq );
00164 *min_pq = NULL;
00165 }
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 void decrease_pq_node_key( struct pq_node* pq_array, int i, int key )
00180 {
00181 struct pq_node tmp;
00182
00183 if( key > pq_array[i].key )
00184 return;
00185
00186 pq_array[i].key = key;
00187 while( i > 0 && pq_array[i].key < pq_array[parent(i)].key )
00188 {
00189 tmp = pq_array[parent(i)];
00190 pq_array[parent(i)] = pq_array[i];
00191 pq_array[i] = tmp;
00192 i = parent(i);
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 void restore_minpq_order( struct pq_node* pq_array, int i, int n )
00206 {
00207 struct pq_node tmp;
00208 int l, r, min = i;
00209
00210 l = left( i );
00211 r = right( i );
00212 if( l < n )
00213 if( pq_array[l].key < pq_array[i].key )
00214 min = l;
00215 if( r < n )
00216 if( pq_array[r].key < pq_array[min].key )
00217 min = r;
00218
00219 if( min != i )
00220 {
00221 tmp = pq_array[min];
00222 pq_array[min] = pq_array[i];
00223 pq_array[i] = tmp;
00224 restore_minpq_order( pq_array, min, n );
00225 }
00226 }