Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

133 Zeilen
4.3 KiB

  1. unit uutlAlgorithm;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. uutlInterfaces;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. generic TutlQuickSort<T> = class(TObject)
  10. public type
  11. IList = specialize IutlList<T>;
  12. IComparer = specialize IutlComparer<T>;
  13. private
  14. class procedure DoSort(
  15. aList: IList;
  16. aComparer: IComparer;
  17. aLow: Integer;
  18. aHigh: Integer);
  19. public
  20. class procedure Sort(
  21. aList: IList;
  22. aComparer: IComparer);
  23. end;
  24. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  25. generic TutlBinarySearch<T> = class(TObject)
  26. public type
  27. IList = specialize IutlReadOnlyList<T>;
  28. IComparer = specialize IutlComparer<T>;
  29. private
  30. class function DoSearch(
  31. aList: IList;
  32. aComparer: IComparer;
  33. const aMin: Integer;
  34. const aMax: Integer;
  35. constref aItem: T;
  36. out aIndex: Integer): Boolean;
  37. public
  38. class function Search(
  39. aList: IList;
  40. aComparer: IComparer;
  41. constref aItem: T;
  42. out aIndex: Integer): Boolean;
  43. end;
  44. implementation
  45. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  46. //TutlQuickSort//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  47. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  48. class procedure TutlQuickSort.DoSort(aList: IList; aComparer: IComparer; aLow: Integer; aHigh: Integer);
  49. var
  50. lo, hi: Integer;
  51. p, tmp: T;
  52. begin
  53. repeat
  54. lo := aLow;
  55. hi := aHigh;
  56. p := aList.GetItem((aLow + aHigh) div 2);
  57. repeat
  58. while (aComparer.Compare(p, aList.GetItem(lo)) > 0) do
  59. lo := lo + 1;
  60. while (aComparer.Compare(p, aList.GetItem(hi)) < 0) do
  61. hi := hi - 1;
  62. if (lo <= hi) then begin
  63. tmp := aList.GetItem(lo);
  64. aList.SetItem(lo, aList.GetItem(hi));
  65. aList.SetItem(hi, tmp);
  66. lo := lo + 1;
  67. hi := hi - 1;
  68. end;
  69. until (lo > hi);
  70. if (hi - aLow < aHigh - lo) then begin
  71. if (aLow < hi) then
  72. DoSort(aList, aComparer, aLow, hi);
  73. aLow := lo;
  74. end else begin
  75. if (lo < aHigh) then
  76. DoSort(aList, aComparer, lo, aHigh);
  77. aHigh := hi;
  78. end;
  79. until (aLow >= aHigh);
  80. end;
  81. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. class procedure TutlQuickSort.Sort(aList: IList; aComparer: IComparer);
  83. begin
  84. DoSort(aList, aComparer, 0, aList.GetCount-1);
  85. end;
  86. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. //TutlBinarySearch///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  88. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  89. class function TutlBinarySearch.DoSearch(aList: IList; aComparer: IComparer; const aMin: Integer; const aMax: Integer;
  90. constref aItem: T; out aIndex: Integer): Boolean;
  91. var
  92. i, cmp: Integer;
  93. begin
  94. if (aMin <= aMax) then begin
  95. i := aMin + Trunc((aMax - aMin) / 2);
  96. cmp := aComparer.Compare(aItem, aList.GetItem(i));
  97. if (cmp = 0) then begin
  98. result := true;
  99. aIndex := i;
  100. end else if (cmp < 0) then
  101. result := DoSearch(aList, aComparer, aMin, i-1, aItem, aIndex)
  102. else if (cmp > 0) then
  103. result := DoSearch(aList, aComparer, i+1, aMax, aItem, aIndex);
  104. end else begin
  105. result := false;
  106. aIndex := aMin;
  107. end;
  108. end;
  109. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  110. class function TutlBinarySearch.Search(aList: IList; aComparer: IComparer; constref aItem: T;
  111. out aIndex: Integer): Boolean;
  112. begin
  113. result := DoSearch(aList, aComparer, 0, aList.GetCount-1, aItem, aIndex);
  114. end;
  115. end.