gpriorityqueue.pp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. {
  2. This file is part of the Free Pascal FCL library.
  3. BSD parts (c) 2011 Vlado Boza
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY;without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$mode objfpc}
  11. unit gpriorityqueue;
  12. interface
  13. uses gvector;
  14. {TCompare is comparing class, which should have class method c(a,b:T):boolean, which returns true is a is less than b}
  15. type
  16. generic TPriorityQueue<T, TCompare>=class
  17. private
  18. type
  19. TContainer=specialize TVector<T>;
  20. var
  21. FData:TContainer;
  22. procedure PushUp();
  23. function Left(a:SizeUInt):SizeUInt;inline;
  24. function Right(a:SizeUInt):SizeUInt;inline;
  25. procedure Heapify(position:SizeUInt);
  26. function Parent(a:SizeUInt):SizeUInt;inline;
  27. public
  28. constructor Create;
  29. destructor Destroy;override;
  30. function Top:T;inline;
  31. procedure Pop;inline;
  32. procedure Push(value:T);inline;
  33. function Size:SizeUInt;inline;
  34. function IsEmpty:boolean;inline;
  35. end;
  36. implementation
  37. constructor TPriorityQueue.Create;
  38. begin
  39. FData:=TContainer.Create;
  40. end;
  41. destructor TPriorityQueue.Destroy;
  42. begin;
  43. FData.Destroy;
  44. end;
  45. function TPriorityQueue.Size:SizeUInt;inline;
  46. begin
  47. Size:=FData.Size;
  48. end;
  49. function TPriorityQueue.IsEmpty:boolean;inline;
  50. begin
  51. IsEmpty:=FData.Size=0;
  52. end;
  53. function TPriorityQueue.Top:T;inline;
  54. begin
  55. Top:=FData[0];
  56. end;
  57. procedure TPriorityQueue.Pop;inline;
  58. begin
  59. if not IsEmpty then begin
  60. FData[0]:=FData.back;
  61. FData.PopBack;
  62. Heapify(0);
  63. end;
  64. end;
  65. procedure TPriorityQueue.PushUp();
  66. var position,np:SizeUInt; temp:T;
  67. begin
  68. position:=FData.Size-1;
  69. while(position>0) do
  70. begin
  71. np := Parent(position);
  72. if(TCompare.c(FData[np],FData[position])) then
  73. begin
  74. temp:=FData[np];
  75. FData[np]:=FData[position];
  76. FData[position]:=temp;
  77. position:=np;
  78. end else
  79. break;
  80. end;
  81. end;
  82. procedure TPriorityQueue.Push(value:T);inline;
  83. begin
  84. FData.PushBack(value);
  85. PushUp();
  86. end;
  87. function TPriorityQueue.Left(a:SizeUInt):SizeUInt;inline;
  88. begin
  89. Left:=((a+1)shl 1)-1;
  90. end;
  91. function TPriorityQueue.Right(a:SizeUInt):SizeUInt;inline;
  92. begin
  93. Right:=(a+1) shl 1;
  94. end;
  95. function TPriorityQueue.Parent(a:SizeUInt):SizeUInt;inline;
  96. begin
  97. Parent:=(a-1)shr 1;
  98. end;
  99. procedure TPriorityQueue.Heapify(position:SizeUInt);
  100. var mpos,l,r:SizeUInt; temp:T;
  101. begin
  102. while(true) do
  103. begin
  104. mpos:=position;
  105. l:=Left(position);
  106. r:=Right(position);
  107. if (l<FData.Size) AND (TCompare.c(FData[mpos],FData[l])) then
  108. mpos:=l;
  109. if (r<FData.Size) AND (TCompare.c(FData[mpos],FData[r])) then
  110. mpos:=r;
  111. if mpos = position then break;
  112. temp:=FData[position];
  113. FData[position]:=FData[mpos];
  114. FData[mpos]:=temp;
  115. position:=mpos;
  116. end;
  117. end;
  118. end.