Pqueue.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //***************************************************************************
  2. //
  3. // PQueue.cpp -- Prototype for Priority Queue class
  4. //
  5. //---------------------------------------------------------------------------//
  6. // Copyright (C) Microsoft Corporation. All rights reserved. //
  7. //===========================================================================//
  8. //----------------------------------------------------------------
  9. // This implementation of a priority queue sorts with the SMALLEST
  10. // item at the front of the queue (used for pathfinding purposes).
  11. //***************************************************************************
  12. //--------------
  13. // Include Files
  14. #ifndef HEAP_H
  15. #include "heap.h"
  16. #endif
  17. #ifndef PQUEUE_H
  18. #include "pqueue.h"
  19. #endif
  20. #include <gameos.hpp>
  21. //***************************************************************************
  22. // Class PriorityQueue
  23. //***************************************************************************
  24. long PriorityQueue::init (long max, long keyMinValue) {
  25. //-------------------------
  26. // Create the queue list...
  27. pqList = (PQNode*)systemHeap->Malloc(sizeof(PQNode) * (max + 2));
  28. gosASSERT (pqList != NULL);
  29. //----------------------------------------------------------------------
  30. // Note that two additional nodes are added, as the first and last nodes
  31. // of the queue list are used as sentinels (to assist implementation
  32. // execution speed)...
  33. maxItems = max + 2;
  34. keyMin = keyMinValue;
  35. return(0);
  36. }
  37. //---------------------------------------------------------------------------
  38. void PriorityQueue::upHeap (long curIndex) {
  39. PQNode startNode = pqList[curIndex];
  40. long stopKey = startNode.key;
  41. pqList[0].key = keyMin;
  42. pqList[0].id = 0xFFFFFFFF;
  43. //--------------------
  44. // sort up the heap...
  45. while (pqList[curIndex/2].key >= stopKey) {
  46. pqList[curIndex] = pqList[curIndex/2];
  47. curIndex /= 2;
  48. }
  49. pqList[curIndex] = startNode;
  50. }
  51. //---------------------------------------------------------------------------
  52. long PriorityQueue::insert (PQNode& item) {
  53. if (numItems == maxItems)
  54. return(1);
  55. pqList[++numItems] = item;
  56. upHeap(numItems);
  57. return(0);
  58. }
  59. //---------------------------------------------------------------------------
  60. void PriorityQueue::downHeap (long curIndex) {
  61. //----------------------------------
  62. // Start at the top from curIndex...
  63. PQNode startNode = pqList[curIndex];
  64. long stopKey = startNode.key;
  65. //----------------------
  66. // Sort down the heap...
  67. while (curIndex <= numItems/2) {
  68. long nextIndex = curIndex << 1;
  69. if ((nextIndex < numItems) && (pqList[nextIndex].key > pqList[nextIndex + 1].key))
  70. nextIndex++;
  71. if (stopKey <= pqList[nextIndex].key)
  72. break;
  73. pqList[curIndex] = pqList[nextIndex];
  74. curIndex = nextIndex;
  75. }
  76. pqList[curIndex] = startNode;
  77. }
  78. //---------------------------------------------------------------------------
  79. void PriorityQueue::remove (PQNode& item) {
  80. item = pqList[1];
  81. pqList[1] = pqList[numItems--];
  82. downHeap(1);
  83. }
  84. //---------------------------------------------------------------------------
  85. void PriorityQueue::change (long itemIndex, long newValue) {
  86. if (newValue > pqList[itemIndex].key) {
  87. pqList[itemIndex].key = newValue;
  88. downHeap(itemIndex);
  89. }
  90. else if (newValue < pqList[itemIndex].key) {
  91. pqList[itemIndex].key = newValue;
  92. upHeap(itemIndex);
  93. }
  94. }
  95. //---------------------------------------------------------------------------
  96. long PriorityQueue::find (long id) {
  97. for (long index = 0; index <= numItems; index++)
  98. if (pqList[index].id == (unsigned long)id)
  99. return(index);
  100. return(0);
  101. }
  102. //---------------------------------------------------------------------------
  103. void PriorityQueue::destroy (void) {
  104. systemHeap->Free(pqList);
  105. pqList = NULL;
  106. maxItems = 0;
  107. numItems = 0;
  108. }
  109. //***************************************************************************