fPQ.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. #include <stdio.h>
  11. #include <util/alloc.h>
  12. /* Priority queue:
  13. * To work, the following have to be defined before this file is
  14. * included:
  15. * - PQTYPE : type of object stored in the queue
  16. * - PQVTYPE : type of priority value
  17. * - N_VAL(pq,n) : macro for (negative) priority value of object n in pq
  18. * - N_IDX(pq,n) : macro for integer index > 0 of n in pq
  19. * - guard, type PQTYPE, with N_VAL(guard) == 0
  20. *
  21. * Priorities are stored as negative numbers, with the item with the least
  22. * negative priority at the head (just after the guard).
  23. */
  24. #ifdef PQ_TYPES
  25. typedef struct {
  26. PQTYPE* pq;
  27. int PQcnt;
  28. int PQsize;
  29. } PQ;
  30. #endif
  31. #ifdef PQ_CODE
  32. static void
  33. PQgen(PQ* pq, int sz, PQTYPE guard)
  34. {
  35. pq->pq = gv_calloc(sz + 1, sizeof(PQTYPE));
  36. pq->pq[0] = guard;
  37. pq->PQsize = sz;
  38. pq->PQcnt = 0;
  39. }
  40. static void
  41. PQfree(PQ* pq, int freeAll)
  42. {
  43. free (pq->pq);
  44. if (freeAll) free (pq);
  45. }
  46. static void
  47. PQinit(PQ* pq)
  48. {
  49. pq->PQcnt = 0;
  50. }
  51. #ifdef PQCHECK
  52. static int
  53. PQcheck (PQ* pq)
  54. {
  55. int i;
  56. for (i = 1; i <= pq->PQcnt; i++) {
  57. if (N_IDX(pq,pq->pq[i]) != i) {
  58. return 1;
  59. }
  60. }
  61. return 0;
  62. }
  63. #endif
  64. static void
  65. PQupheap(PQ* ppq, int k)
  66. {
  67. PQTYPE* pq = ppq->pq;
  68. PQTYPE x = pq[k];
  69. PQVTYPE v = N_VAL(ppq,x);
  70. int next = k/2;
  71. PQTYPE n;
  72. while (N_VAL(ppq,n = pq[next]) < v) {
  73. pq[k] = n;
  74. N_IDX(ppq,n) = k;
  75. k = next;
  76. next /= 2;
  77. }
  78. pq[k] = x;
  79. N_IDX(ppq,x) = k;
  80. }
  81. static int
  82. PQinsert(PQ* pq, PQTYPE np)
  83. {
  84. if (pq->PQcnt == pq->PQsize) {
  85. agerrorf("Heap overflow\n");
  86. return (1);
  87. }
  88. pq->PQcnt++;
  89. pq->pq[pq->PQcnt] = np;
  90. PQupheap (pq, pq->PQcnt);
  91. #ifdef PQCHECK
  92. PQcheck(pq);
  93. #endif
  94. return 0;
  95. }
  96. static void
  97. PQdownheap (PQ* ppq, int k)
  98. {
  99. PQTYPE* pq = ppq->pq;
  100. PQTYPE x = pq[k];
  101. PQVTYPE v = N_VAL(ppq,x);
  102. int lim = ppq->PQcnt/2;
  103. PQTYPE n;
  104. int j;
  105. while (k <= lim) {
  106. j = k+k;
  107. n = pq[j];
  108. if (j < ppq->PQcnt) {
  109. if (N_VAL(ppq,n) < N_VAL(ppq,pq[j+1])) {
  110. j++;
  111. n = pq[j];
  112. }
  113. }
  114. if (v >= N_VAL(ppq,n)) break;
  115. pq[k] = n;
  116. N_IDX(ppq,n) = k;
  117. k = j;
  118. }
  119. pq[k] = x;
  120. N_IDX(ppq,x) = k;
  121. }
  122. static PQTYPE
  123. PQremove (PQ* pq)
  124. {
  125. PQTYPE n;
  126. if (pq->PQcnt) {
  127. n = pq->pq[1];
  128. pq->pq[1] = pq->pq[pq->PQcnt];
  129. pq->PQcnt--;
  130. if (pq->PQcnt) PQdownheap (pq, 1);
  131. #ifdef PQCHECK
  132. PQcheck(pq);
  133. #endif
  134. return n;
  135. }
  136. else return pq->pq[0];
  137. }
  138. static void
  139. PQupdate (PQ* pq, PQTYPE n, PQVTYPE d)
  140. {
  141. N_VAL(pq,n) = d;
  142. PQupheap (pq, N_IDX(pq,n));
  143. #ifdef PQCHECK
  144. PQcheck(pq);
  145. #endif
  146. }
  147. #if defined(DEBUG) && DEBUG > 1
  148. static void
  149. PQprint (PQ* pq)
  150. {
  151. int i;
  152. PQTYPE n;
  153. fprintf (stderr, "Q: ");
  154. for (i = 1; i <= pq->PQcnt; i++) {
  155. n = pq->pq[i];
  156. fprintf (stderr, "(%d:%f) ", N_IDX(pq,n), N_VAL(pq,n));
  157. }
  158. fprintf (stderr, "\n");
  159. }
  160. #endif
  161. #endif