PARP Research Group University of Murcia, Spain


examples/OpenCV/siftDetector/hess/minpq.cpp

00001 /*
00002   Functions and structures for implementing a minimizing priority queue.
00003   
00004   Copyright (C) 2006-2007  Rob Hess <hess@eecs.oregonstate.edu>
00005 
00006   @version 1.1.1-20070913
00007 */
00008 
00009 #include "minpq.h"
00010 #include "utils.h"
00011 
00012 #include <limits.h>
00013 
00014 /************************* Local Function Prototypes *************************/
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 /************************** Local Inline Functions ***************************/
00021 
00022 /* returns the array index of element i's parent */
00023 static inline int parent( int i )
00024 {
00025   return ( i - 1 ) / 2;
00026 }
00027 
00028 
00029 /* returns the array index of element i's right child */
00030 static inline int right( int i )
00031 {
00032   return 2 * i + 2;
00033 }
00034 
00035 
00036 /* returns the array index of element i's left child */
00037 static inline int left( int i )
00038 {
00039   return 2 * i + 1;
00040 }
00041 
00042 
00043 /********************** Functions prototyped in minpq.h **********************/
00044 
00045 
00046 /*
00047   Creates a new minimizing priority queue.
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   /* double array allocation if necessary */
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   Returns the element of a minimizing priority queue with the smallest key
00101   without removing it from the queue.
00102   
00103   @param min_pq a minimizing priority queue
00104   
00105   @return Returns the element of \a min_pq with the smallest key or NULL
00106     if \a min_pq is empty
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   Removes and returns the element of a minimizing priority queue with the
00122   smallest key.
00123   
00124   @param min_pq a minimizing priority queue
00125   
00126   @return Returns the element of \a min_pq with the smallest key of NULL
00127     if \a min_pq is empty
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   De-allocates the memory held by a minimizing priorioty queue
00149   
00150   @param min_pq pointer to a minimizing priority queue
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 /************************ Functions prototyped here **************************/
00170 
00171 /*
00172   Decrease a minimizing pq element's key, rearranging the pq if necessary
00173 
00174   @param pq_array minimizing priority queue array
00175   @param i index of the element whose key is to be decreased
00176   @param key new value of element <EM>i</EM>'s key; if greater than current
00177     key, no action is taken
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   Recursively restores correct priority queue order to a minimizing pq array
00200 
00201   @param pq_array a minimizing priority queue array
00202   @param i index at which to start reordering
00203   @param n number of elements in \a pq_array
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 }



QVision framework. PARP research group, copyright 2007, 2008.