heap.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* LIBDGL -- a Directed Graph Library implementation
  2. * Copyright (C) 2002 Roberto Micarelli
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. /* best view tabstop=4
  19. */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include "type.h"
  23. #include "heap.h"
  24. void dglHeapInit(dglHeap_s * pheap)
  25. {
  26. pheap->index = 0;
  27. pheap->count = 0;
  28. pheap->block = 256;
  29. pheap->pnode = NULL;
  30. }
  31. void dglHeapFree(dglHeap_s * pheap, dglHeapCancelItem_fn pfnCancelItem)
  32. {
  33. int iItem;
  34. if (pheap->pnode) {
  35. if (pfnCancelItem) {
  36. for (iItem = 0; iItem <= pheap->index; iItem++) {
  37. pfnCancelItem(pheap, &pheap->pnode[iItem]);
  38. }
  39. }
  40. free(pheap->pnode);
  41. }
  42. pheap->pnode = NULL;
  43. }
  44. int dglHeapInsertMin(dglHeap_s * pheap,
  45. long key, unsigned char flags, dglHeapData_u value)
  46. {
  47. long i;
  48. if (pheap->index >= pheap->count - 1) {
  49. pheap->count += pheap->block;
  50. if ((pheap->pnode =
  51. realloc(pheap->pnode,
  52. sizeof(dglHeapNode_s) * pheap->count)) == NULL)
  53. return -1;
  54. }
  55. i = ++pheap->index;
  56. while (i != 1 && key < pheap->pnode[i / 2].key) {
  57. pheap->pnode[i] = pheap->pnode[i / 2];
  58. i /= 2;
  59. }
  60. pheap->pnode[i].key = key;
  61. pheap->pnode[i].flags = flags;
  62. pheap->pnode[i].value = value;
  63. return i;
  64. }
  65. int dglHeapExtractMin(dglHeap_s * pheap, dglHeapNode_s * pnoderet)
  66. {
  67. dglHeapNode_s temp;
  68. long iparent, ichild;
  69. if (pheap->index == 0)
  70. return 0; /* empty heap */
  71. *pnoderet = pheap->pnode[1];
  72. temp = pheap->pnode[pheap->index--];
  73. iparent = 1;
  74. ichild = 2;
  75. while (ichild <= pheap->index) {
  76. if (ichild < pheap->index &&
  77. pheap->pnode[ichild].key > pheap->pnode[ichild + 1].key) {
  78. ichild++;
  79. }
  80. if (temp.key <= pheap->pnode[ichild].key)
  81. break;
  82. pheap->pnode[iparent] = pheap->pnode[ichild];
  83. iparent = ichild;
  84. ichild *= 2;
  85. }
  86. pheap->pnode[iparent] = temp;
  87. return 1;
  88. }
  89. int dglHeapInsertMax(dglHeap_s * pheap,
  90. long key, unsigned char flags, dglHeapData_u value)
  91. {
  92. long i;
  93. if (pheap->index >= pheap->count - 1) {
  94. pheap->count += pheap->block;
  95. if ((pheap->pnode =
  96. realloc(pheap->pnode,
  97. sizeof(dglHeapNode_s) * pheap->count)) == NULL)
  98. return -1;
  99. }
  100. i = ++pheap->index;
  101. while (i != 1 && key > pheap->pnode[i / 2].key) {
  102. pheap->pnode[i] = pheap->pnode[i / 2];
  103. i /= 2;
  104. }
  105. pheap->pnode[i].key = key;
  106. pheap->pnode[i].flags = flags;
  107. pheap->pnode[i].value = value;
  108. return i;
  109. }
  110. int dglHeapExtractMax(dglHeap_s * pheap, dglHeapNode_s * pnoderet)
  111. {
  112. dglHeapNode_s temp;
  113. long iparent, ichild;
  114. if (pheap->index == 0)
  115. return 0; /* empty heap */
  116. *pnoderet = pheap->pnode[1];
  117. temp = pheap->pnode[pheap->index--];
  118. iparent = 1;
  119. ichild = 2;
  120. while (ichild <= pheap->index) {
  121. if (ichild < pheap->index &&
  122. pheap->pnode[ichild].key < pheap->pnode[ichild + 1].key) {
  123. ichild++;
  124. }
  125. if (temp.key >= pheap->pnode[ichild].key)
  126. break;
  127. pheap->pnode[iparent] = pheap->pnode[ichild];
  128. iparent = ichild;
  129. ichild *= 2;
  130. }
  131. pheap->pnode[iparent] = temp;
  132. return 1;
  133. }