fPQ.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. /* Priority Queue Code for shortest path in graph */
  11. #include "config.h"
  12. #include <assert.h>
  13. #include <util/alloc.h>
  14. #include <ortho/fPQ.h>
  15. static snode** pq;
  16. static int PQcnt;
  17. static snode guard;
  18. static int PQsize;
  19. void
  20. PQgen(int sz)
  21. {
  22. if (!pq) {
  23. pq = gv_calloc(sz + 1, sizeof(snode*));
  24. pq[0] = &guard;
  25. PQsize = sz;
  26. }
  27. PQcnt = 0;
  28. }
  29. void
  30. PQfree(void)
  31. {
  32. free (pq);
  33. pq = NULL;
  34. PQcnt = 0;
  35. }
  36. void
  37. PQinit(void)
  38. {
  39. PQcnt = 0;
  40. }
  41. void
  42. PQcheck (void)
  43. {
  44. int i;
  45. for (i = 1; i <= PQcnt; i++) {
  46. if (N_IDX(pq[i]) != i) {
  47. assert (0);
  48. }
  49. }
  50. }
  51. void
  52. PQupheap(int k)
  53. {
  54. snode* x = pq[k];
  55. int v = x->n_val;
  56. int next = k/2;
  57. snode* n;
  58. while (N_VAL(n = pq[next]) < v) {
  59. pq[k] = n;
  60. N_IDX(n) = k;
  61. k = next;
  62. next /= 2;
  63. }
  64. pq[k] = x;
  65. N_IDX(x) = k;
  66. }
  67. int
  68. PQ_insert(snode* np)
  69. {
  70. if (PQcnt == PQsize) {
  71. agerrorf("Heap overflow\n");
  72. return 1;
  73. }
  74. PQcnt++;
  75. pq[PQcnt] = np;
  76. PQupheap (PQcnt);
  77. PQcheck();
  78. return 0;
  79. }
  80. void
  81. PQdownheap (int k)
  82. {
  83. snode* x = pq[k];
  84. int v = N_VAL(x);
  85. int lim = PQcnt/2;
  86. snode* n;
  87. int j;
  88. while (k <= lim) {
  89. j = k+k;
  90. n = pq[j];
  91. if (j < PQcnt) {
  92. if (N_VAL(n) < N_VAL(pq[j+1])) {
  93. j++;
  94. n = pq[j];
  95. }
  96. }
  97. if (v >= N_VAL(n)) break;
  98. pq[k] = n;
  99. N_IDX(n) = k;
  100. k = j;
  101. }
  102. pq[k] = x;
  103. N_IDX(x) = k;
  104. }
  105. snode*
  106. PQremove (void)
  107. {
  108. snode* n;
  109. if (PQcnt) {
  110. n = pq[1];
  111. pq[1] = pq[PQcnt];
  112. PQcnt--;
  113. if (PQcnt) PQdownheap (1);
  114. PQcheck();
  115. return n;
  116. }
  117. else return 0;
  118. }
  119. void
  120. PQupdate (snode* n, int d)
  121. {
  122. N_VAL(n) = d;
  123. PQupheap (n->n_idx);
  124. PQcheck();
  125. }
  126. void
  127. PQprint (void)
  128. {
  129. int i;
  130. snode* n;
  131. fprintf (stderr, "Q: ");
  132. for (i = 1; i <= PQcnt; i++) {
  133. n = pq[i];
  134. fprintf (stderr, "%d(%d:%d) ",
  135. n->index, N_IDX(n), N_VAL(n));
  136. }
  137. fprintf (stderr, "\n");
  138. }