minpq.c
上传用户:lwxipeng
上传日期:2022-05-16
资源大小:15982k
文件大小:5k
源码类别:

视频捕捉/采集

开发平台:

Visual C++

  1. /*
  2. Functions and structures for implementing a minimizing priority queue.
  3. Copyright (C) 2006  Rob Hess <hess@eecs.oregonstate.edu>
  4. @version 1.1.1-20070330
  5. */
  6. #include "minpq.h"
  7. #include "utils.h"
  8. #include <limits.h>
  9. /************************* Local Function Prototypes *************************/
  10. void restore_minpq_order( struct pq_node*, int, int );
  11. void decrease_pq_node_key( struct pq_node*, int, int );
  12. /************************** Local Inline Functions ***************************/
  13. /* returns the array index of element i's parent */
  14. static __inline int parent( int i )
  15. {
  16. return ( i - 1 ) / 2;
  17. }
  18. /* returns the array index of element i's right child */
  19. static __inline int right( int i )
  20. {
  21. return 2 * i + 2;
  22. }
  23. /* returns the array index of element i's left child */
  24. static __inline int left( int i )
  25. {
  26. return 2 * i + 1;
  27. }
  28. /********************** Functions prototyped in minpq.h **********************/
  29. /*
  30. Creates a new minimizing priority queue.
  31. */
  32. struct min_pq* minpq_init()
  33. {
  34. struct min_pq* min_pq;
  35. min_pq = malloc( sizeof( struct min_pq ) );
  36. min_pq->pq_array = calloc( MINPQ_INIT_NALLOCD, sizeof( struct pq_node ) );
  37. min_pq->nallocd = MINPQ_INIT_NALLOCD;
  38. min_pq->n = 0;
  39. return min_pq;
  40. }
  41. /**
  42. Inserts an element into a minimizing priority queue.
  43. @param min_pq a minimizing priority queue
  44. @param data the data to be inserted
  45. @param key the key to be associated with a data
  46. @return Returns 0 on success or 1 on failure.
  47. */
  48. int minpq_insert( struct min_pq* min_pq, void* data, int key )
  49. {
  50. int n = min_pq->n;
  51. /* double array allocation if necessary */
  52. if( min_pq->nallocd == n )
  53. {
  54. min_pq->nallocd = array_double( &min_pq->pq_array, min_pq->nallocd,
  55. sizeof( struct pq_node ) );
  56. if( ! min_pq->nallocd )
  57. {
  58. fprintf( stderr, "Warning: unable to allocate memory, %s, line %dn",
  59. __FILE__, __LINE__ );
  60. return 1;
  61. }
  62. }
  63. min_pq->pq_array[n].data = data;
  64. min_pq->pq_array[n].key = INT_MAX;
  65. decrease_pq_node_key( min_pq->pq_array, min_pq->n, key );
  66. min_pq->n++;
  67. return 0;
  68. }
  69. /*
  70. Returns the element of a minimizing priority queue with the smallest key
  71. without removing it from the queue.
  72. @param min_pq a minimizing priority queue
  73. @return Returns the element of a min_pq with the smallest key or NULL
  74. if a min_pq is empty
  75. */
  76. void* minpq_get_min( struct min_pq* min_pq )
  77. {
  78. if( min_pq->n < 1 )
  79. {
  80. fprintf( stderr, "Warning: PQ empty, %s line %dn", __FILE__, __LINE__ );
  81. return NULL;
  82. }
  83. return min_pq->pq_array[0].data;
  84. }
  85. /*
  86. Removes and returns the element of a minimizing priority queue with the
  87. smallest key.
  88. @param min_pq a minimizing priority queue
  89. @return Returns the element of a min_pq with the smallest key of NULL
  90. if a min_pq is empty
  91. */
  92. void* minpq_extract_min( struct min_pq* min_pq )
  93. {
  94. void* data;
  95. if( min_pq->n < 1 )
  96. {
  97. fprintf( stderr, "Warning: PQ empty, %s line %dn", __FILE__, __LINE__ );
  98. return NULL;
  99. }
  100. data = min_pq->pq_array[0].data;
  101. min_pq->n--;
  102. min_pq->pq_array[0] = min_pq->pq_array[min_pq->n];
  103. restore_minpq_order( min_pq->pq_array, 0, min_pq->n );
  104. return data;
  105. }
  106. /*
  107. De-allocates the memory held by a minimizing priorioty queue
  108. @param min_pq pointer to a minimizing priority queue
  109. */
  110. void minpq_release( struct min_pq** min_pq )
  111. {
  112. if( ! min_pq )
  113. {
  114. fprintf( stderr, "Warning: NULL pointer error, %s line %dn", __FILE__,
  115. __LINE__ );
  116. return;
  117. }
  118. if( *min_pq  &&  (*min_pq)->pq_array )
  119. {
  120. free( (*min_pq)->pq_array );
  121. free( *min_pq );
  122. *min_pq = NULL;
  123. }
  124. }
  125. /************************ Functions prototyped here **************************/
  126. /*
  127. Decrease a minimizing pq element's key, rearranging the pq if necessary
  128. @param pq_array minimizing priority queue array
  129. @param i index of the element whose key is to be decreased
  130. @param key new value of element <EM>i</EM>'s key; if greater than current
  131. key, no action is taken
  132. */
  133. void decrease_pq_node_key( struct pq_node* pq_array, int i, int key )
  134. {
  135. struct pq_node tmp;
  136. if( key > pq_array[i].key )
  137. return;
  138. pq_array[i].key = key;
  139. while( i > 0  &&  pq_array[i].key < pq_array[parent(i)].key )
  140. {
  141. tmp = pq_array[parent(i)];
  142. pq_array[parent(i)] = pq_array[i];
  143. pq_array[i] = tmp;
  144. i = parent(i);
  145. }
  146. }
  147. /*
  148. Recursively restores correct priority queue order to a minimizing pq array
  149. @param pq_array a minimizing priority queue array
  150. @param i index at which to start reordering
  151. @param n number of elements in a pq_array
  152. */
  153. void restore_minpq_order( struct pq_node* pq_array, int i, int n )
  154. {
  155. struct pq_node tmp;
  156. int l, r, min = i;
  157. l = left( i );
  158. r = right( i );
  159. if( l < n )
  160. if( pq_array[l].key < pq_array[i].key )
  161. min = l;
  162. if( r < n )
  163. if( pq_array[r].key < pq_array[min].key )
  164. min = r;
  165. if( min != i )
  166. {
  167. tmp = pq_array[min];
  168. pq_array[min] = pq_array[i];
  169. pq_array[i] = tmp;
  170. restore_minpq_order( pq_array, min, n );
  171. }
  172. }