Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

priority_queue.h

Go to the documentation of this file.
00001 #ifndef DEF_PRIORITY_QUEUE 00002 #define DEF_PRIORITY_QUEUE 00003 00004 /* ---------------------------------------------------------------------------- 00005 @COPYRIGHT : 00006 Copyright 1993,1994,1995 David MacDonald, 00007 McConnell Brain Imaging Centre, 00008 Montreal Neurological Institute, McGill University. 00009 Permission to use, copy, modify, and distribute this 00010 software and its documentation for any purpose and without 00011 fee is hereby granted, provided that the above copyright 00012 notice appear in all copies. The author and McGill University 00013 make no representations about the suitability of this 00014 software for any purpose. It is provided "as is" without 00015 express or implied warranty. 00016 ---------------------------------------------------------------------------- */ 00017 00018 00019 #include <volume_io/arrays.h> 00020 00021 /* ----------------------------- MNI Header ----------------------------------- 00022 @NAME : priority_queue.h 00023 @INPUT : 00024 @OUTPUT : 00025 @RETURNS : 00026 @DESCRIPTION: Macros for maintaining priority queues of any element type. 00027 @METHOD : The linear array representation of a binary heap is used to 00028 : to allow logarithmic insertions of any value and deletion 00029 : of the top element 00030 @GLOBALS : 00031 @CALLS : 00032 @CREATED : David MacDonald 00033 @MODIFIED : 00034 ---------------------------------------------------------------------------- */ 00035 00036 /* ----------------------------- MNI Header ----------------------------------- 00037 @NAME : PRIORITY_QUEUE_STRUCT 00038 @INPUT : type 00039 @OUTPUT : 00040 @RETURNS : 00041 @DESCRIPTION: Macro to define a priority queue of elements of type 'type'. 00042 @METHOD : 00043 @GLOBALS : 00044 @CALLS : 00045 @CREATED : David MacDonald 00046 @MODIFIED : 00047 ---------------------------------------------------------------------------- */ 00048 00049 #define PRIORITY_QUEUE_STRUCT( type ) \ 00050 struct \ 00051 { \ 00052 int n_alloced; \ 00053 int n_entries; \ 00054 float *priorities; \ 00055 type *entries; \ 00056 } 00057 00058 /* ----------------------------- MNI Header ----------------------------------- 00059 @NAME : INITIALIZE_PRIORITY_QUEUE 00060 @INPUT : q 00061 @OUTPUT : 00062 @RETURNS : 00063 @DESCRIPTION: Macro to initialize a priority queue to empty. 00064 @METHOD : 00065 @GLOBALS : 00066 @CALLS : 00067 @CREATED : David MacDonald 00068 @MODIFIED : 00069 ---------------------------------------------------------------------------- */ 00070 00071 #define INITIALIZE_PRIORITY_QUEUE( q ) \ 00072 { \ 00073 (q).n_alloced = 0; \ 00074 (q).n_entries = 1; \ 00075 (q).priorities = NULL; \ 00076 (q).entries = NULL; \ 00077 } 00078 00079 /* ----------------------------- MNI Header ----------------------------------- 00080 @NAME : INSERT_IN_PRIORITY_QUEUE 00081 @INPUT : q 00082 : entry - element to insert 00083 : priority - priority of the element 00084 @OUTPUT : status 00085 @RETURNS : 00086 @DESCRIPTION: Macro to insert an entry in the priority queue. 00087 @METHOD : 00088 @GLOBALS : 00089 @CALLS : 00090 @CREATED : David MacDonald 00091 @MODIFIED : 00092 ---------------------------------------------------------------------------- */ 00093 00094 #define INSERT_IN_PRIORITY_QUEUE( q, entry, priority ) \ 00095 { \ 00096 int _index, _next_index; \ 00097 \ 00098 SET_ARRAY_SIZE( (q).entries, (q).n_alloced, \ 00099 (q).n_entries+1, DEFAULT_CHUNK_SIZE ); \ 00100 SET_ARRAY_SIZE( (q).priorities, (q).n_alloced, \ 00101 (q).n_entries+1, DEFAULT_CHUNK_SIZE ); \ 00102 \ 00103 _index = (q).n_entries; \ 00104 \ 00105 while( _index > 1 ) \ 00106 { \ 00107 _next_index = _index >> 1; \ 00108 if( (Real) (q).priorities[_next_index] > (Real) (priority) ) \ 00109 break; \ 00110 (q).priorities[_index] = (float) (q).priorities[_next_index]; \ 00111 (q).entries[_index] = (q).entries[_next_index]; \ 00112 _index = _next_index; \ 00113 } \ 00114 \ 00115 (q).priorities[_index] = (float) (priority); \ 00116 (q).entries[_index] = entry; \ 00117 \ 00118 ++(q).n_entries; \ 00119 \ 00120 (q).n_alloced = (q).n_entries; \ 00121 } 00122 00123 /* ----------------------------- MNI Header ----------------------------------- 00124 @NAME : NUMBER_IN_PRIORITY_QUEUE 00125 @INPUT : q 00126 @OUTPUT : 00127 @RETURNS : 00128 @DESCRIPTION: Returns the number of entries in the priority queue. 00129 @METHOD : 00130 @GLOBALS : 00131 @CALLS : 00132 @CREATED : David MacDonald 00133 @MODIFIED : 00134 ---------------------------------------------------------------------------- */ 00135 00136 #define NUMBER_IN_PRIORITY_QUEUE( q ) ((q).n_entries - 1) 00137 00138 /* ----------------------------- MNI Header ----------------------------------- 00139 @NAME : IS_PRIORITY_QUEUE_EMPTY 00140 @INPUT : 00141 @OUTPUT : 00142 @RETURNS : TRUE or FALSE 00143 @DESCRIPTION: Returns TRUE if the priority queue is empty 00144 @METHOD : 00145 @GLOBALS : 00146 @CALLS : 00147 @CREATED : David MacDonald 00148 @MODIFIED : 00149 ---------------------------------------------------------------------------- */ 00150 00151 #define IS_PRIORITY_QUEUE_EMPTY( q ) (NUMBER_IN_PRIORITY_QUEUE(q) == 0) 00152 00153 /* ----------------------------- MNI Header ----------------------------------- 00154 @NAME : REMOVE_FROM_QUEUE 00155 @INPUT : q 00156 @OUTPUT : entry 00157 @RETURNS : 00158 @DESCRIPTION: Removes the first entry (highest priority) from the queue, 00159 : and stores it in 'entry'. 00160 : Then it shifts up entries in logarithmic time. 00161 @METHOD : 00162 @GLOBALS : 00163 @CALLS : 00164 @CREATED : David MacDonald 00165 @CALLS : 00166 @CREATED : David MacDonald 00167 @MODIFIED : 00168 ---------------------------------------------------------------------------- */ 00169 00170 #define REMOVE_FROM_PRIORITY_QUEUE( q, entry, priority ) \ 00171 { \ 00172 if( !IS_PRIORITY_QUEUE_EMPTY(q) ) \ 00173 { \ 00174 int _index, _next_index; \ 00175 \ 00176 entry = (q).entries[1]; \ 00177 priority = (Real) (q).priorities[1]; \ 00178 \ 00179 _index = 1; \ 00180 _next_index = 2; \ 00181 \ 00182 while( _next_index < (q).n_entries ) \ 00183 { \ 00184 if( _next_index+1 < (q).n_entries && \ 00185 (q).priorities[_next_index+1] > \ 00186 (q).priorities[_next_index] ) \ 00187 { \ 00188 ++_next_index; \ 00189 } \ 00190 \ 00191 if( (q).priorities[(q).n_entries-1] >= \ 00192 (q).priorities[_next_index] ) \ 00193 { \ 00194 break; \ 00195 } \ 00196 else \ 00197 { \ 00198 (q).priorities[_index] = (q).priorities[_next_index]; \ 00199 (q).entries[_index] = (q).entries[_next_index]; \ 00200 \ 00201 _index = _next_index; \ 00202 _next_index <<= 1; \ 00203 } \ 00204 } \ 00205 \ 00206 if( (q).n_entries > 2 ) \ 00207 { \ 00208 (q).priorities[_index] = (q).priorities[(q).n_entries-1]; \ 00209 (q).entries[_index] = (q).entries[(q).n_entries-1]; \ 00210 } \ 00211 \ 00212 --(q).n_entries; \ 00213 } \ 00214 } 00215 00216 #define GET_TOP_PRIORITY( q ) \ 00217 ( IS_PRIORITY_QUEUE_EMPTY(q) ? 0.0 : (Real) (q).priorities[1] ) 00218 00219 /* ----------------------------- MNI Header ----------------------------------- 00220 @NAME : DELETE_PRIORITY_QUEUE 00221 @INPUT : q 00222 @OUTPUT : status 00223 @RETURNS : 00224 @DESCRIPTION: Deletes the priority queue. 00225 @METHOD : 00226 @GLOBALS : 00227 @CALLS : 00228 @CREATED : David MacDonald 00229 @MODIFIED : 00230 ---------------------------------------------------------------------------- */ 00231 00232 #define DELETE_PRIORITY_QUEUE( q ) \ 00233 { \ 00234 if( (q).n_alloced > 0 ) \ 00235 { \ 00236 FREE( (q).entries ); \ 00237 FREE( (q).priorities ); \ 00238 } \ 00239 } 00240 00241 00242 #endif

Generated on Wed Jul 28 09:10:57 2004 for BICPL by doxygen 1.3.7