Преглед изворни кода

+ keep track of the pivot index in all quicksort implementations. No functional changes,
but will be used to prevent overlap in the divided subregions and also infinite loops
in case of an incorrect compare function.

git-svn-id: trunk@41222 -

nickysn пре 6 година
родитељ
комит
26486bbaea
1 измењених фајлова са 41 додато и 16 уклоњено
  1. 41 16
      rtl/inc/sortbase.pp

+ 41 - 16
rtl/inc/sortbase.pp

@@ -67,13 +67,14 @@ implementation
 Procedure QuickSort_PtrList_NoContext(ItemPtrs: PPointer; L, R : Longint;
                                       Comparer: TListSortComparer_NoContext);
 var
-  I, J : Longint;
+  I, J, PivotIdx : Longint;
   P, Q : Pointer;
 begin
  repeat
    I := L;
    J := R;
-   P := ItemPtrs[ (L + R) div 2 ];
+   PivotIdx := (L + R) div 2;
+   P := ItemPtrs[PivotIdx];
    repeat
      while Comparer(P, ItemPtrs[i]) > 0 do
        Inc(I);
@@ -84,6 +85,10 @@ begin
        Q := ItemPtrs[I];
        ItemPtrs[I] := ItemPtrs[J];
        ItemPtrs[J] := Q;
+       if PivotIdx = I then
+         PivotIdx := J
+       else if PivotIdx = J then
+         PivotIdx := I;
        Inc(I);
        Dec(J);
      end;
@@ -117,13 +122,14 @@ procedure QuickSort_PtrList_Context(ItemPtrs: PPointer; ItemCount: SizeUInt; Com
 
   procedure QuickSort(L, R : Longint);
   var
-    I, J : Longint;
+    I, J, PivotIdx : Longint;
     P, Q : Pointer;
   begin
     repeat
       I := L;
       J := R;
-      P := ItemPtrs[ (L + R) div 2 ];
+      PivotIdx := (L + R) div 2;
+      P := ItemPtrs[PivotIdx];
       repeat
         while Comparer(P, ItemPtrs[I], Context) > 0 do
           Inc(I);
@@ -134,6 +140,11 @@ procedure QuickSort_PtrList_Context(ItemPtrs: PPointer; ItemCount: SizeUInt; Com
           Q := ItemPtrs[I];
           ItemPtrs[I] := ItemPtrs[J];
           ItemPtrs[J] := Q;
+          if PivotIdx = I then
+            PivotIdx := J
+          else if PivotIdx = J then
+            PivotIdx := I;
+
           Inc(I);
           Dec(J);
         end;
@@ -169,13 +180,14 @@ var
 
   procedure QuickSort(L, R : Longint);
   var
-    I, J : Longint;
+    I, J, PivotIdx : Longint;
     P : Pointer;
   begin
     repeat
       I := L;
       J := R;
-      P := Items + ItemSize*((L + R) div 2);
+      PivotIdx := (L + R) div 2;
+      P := Items + ItemSize*PivotIdx;
       repeat
         while Comparer(P, Items + ItemSize*I, Context) > 0 do
           Inc(I);
@@ -188,10 +200,16 @@ var
             Move((Items + ItemSize*I)^, TempBuf^, ItemSize);
             Move((Items + ItemSize*J)^, (Items + ItemSize*I)^, ItemSize);
             Move(TempBuf^, (Items + ItemSize*J)^, ItemSize);
-            if P = (Items + ItemSize*I) then
-              P := Items + ItemSize*J
-            else if P = (Items + ItemSize*J) then
-              P := Items + ItemSize*I;
+            if PivotIdx = I then
+            begin
+              PivotIdx := J;
+              P := Items + ItemSize*PivotIdx
+            end
+            else if PivotIdx = J then
+            begin
+              PivotIdx := I;
+              P := Items + ItemSize*PivotIdx;
+            end;
           end;
           Inc(I);
           Dec(J);
@@ -232,13 +250,14 @@ procedure QuickSort_ItemList_CustomItemExchanger_Context(
 
   procedure QuickSort(L, R : Longint);
   var
-    I, J : Longint;
+    I, J, PivotIdx : Longint;
     P : Pointer;
   begin
     repeat
       I := L;
       J := R;
-      P := Items + ItemSize*((L + R) div 2);
+      PivotIdx := (L + R) div 2;
+      P := Items + ItemSize*PivotIdx;
       repeat
         while Comparer(P, Items + ItemSize*I, Context) > 0 do
           Inc(I);
@@ -249,10 +268,16 @@ procedure QuickSort_ItemList_CustomItemExchanger_Context(
           if I < J then
           begin
             Exchanger(Items + ItemSize*I, Items + ItemSize*J, Context);
-            if P = (Items + ItemSize*I) then
-              P := Items + ItemSize*J
-            else if P = (Items + ItemSize*J) then
-              P := Items + ItemSize*I;
+            if PivotIdx = I then
+            begin
+              PivotIdx := J;
+              P := Items + ItemSize*PivotIdx
+            end
+            else if PivotIdx = J then
+            begin
+              PivotIdx := I;
+              P := Items + ItemSize*PivotIdx;
+            end;
           end;
           Inc(I);
           Dec(J);