Browse Source

+ 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 years ago
parent
commit
26486bbaea
1 changed files with 41 additions and 16 deletions
  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;
 Procedure QuickSort_PtrList_NoContext(ItemPtrs: PPointer; L, R : Longint;
                                       Comparer: TListSortComparer_NoContext);
                                       Comparer: TListSortComparer_NoContext);
 var
 var
-  I, J : Longint;
+  I, J, PivotIdx : Longint;
   P, Q : Pointer;
   P, Q : Pointer;
 begin
 begin
  repeat
  repeat
    I := L;
    I := L;
    J := R;
    J := R;
-   P := ItemPtrs[ (L + R) div 2 ];
+   PivotIdx := (L + R) div 2;
+   P := ItemPtrs[PivotIdx];
    repeat
    repeat
      while Comparer(P, ItemPtrs[i]) > 0 do
      while Comparer(P, ItemPtrs[i]) > 0 do
        Inc(I);
        Inc(I);
@@ -84,6 +85,10 @@ begin
        Q := ItemPtrs[I];
        Q := ItemPtrs[I];
        ItemPtrs[I] := ItemPtrs[J];
        ItemPtrs[I] := ItemPtrs[J];
        ItemPtrs[J] := Q;
        ItemPtrs[J] := Q;
+       if PivotIdx = I then
+         PivotIdx := J
+       else if PivotIdx = J then
+         PivotIdx := I;
        Inc(I);
        Inc(I);
        Dec(J);
        Dec(J);
      end;
      end;
@@ -117,13 +122,14 @@ procedure QuickSort_PtrList_Context(ItemPtrs: PPointer; ItemCount: SizeUInt; Com
 
 
   procedure QuickSort(L, R : Longint);
   procedure QuickSort(L, R : Longint);
   var
   var
-    I, J : Longint;
+    I, J, PivotIdx : Longint;
     P, Q : Pointer;
     P, Q : Pointer;
   begin
   begin
     repeat
     repeat
       I := L;
       I := L;
       J := R;
       J := R;
-      P := ItemPtrs[ (L + R) div 2 ];
+      PivotIdx := (L + R) div 2;
+      P := ItemPtrs[PivotIdx];
       repeat
       repeat
         while Comparer(P, ItemPtrs[I], Context) > 0 do
         while Comparer(P, ItemPtrs[I], Context) > 0 do
           Inc(I);
           Inc(I);
@@ -134,6 +140,11 @@ procedure QuickSort_PtrList_Context(ItemPtrs: PPointer; ItemCount: SizeUInt; Com
           Q := ItemPtrs[I];
           Q := ItemPtrs[I];
           ItemPtrs[I] := ItemPtrs[J];
           ItemPtrs[I] := ItemPtrs[J];
           ItemPtrs[J] := Q;
           ItemPtrs[J] := Q;
+          if PivotIdx = I then
+            PivotIdx := J
+          else if PivotIdx = J then
+            PivotIdx := I;
+
           Inc(I);
           Inc(I);
           Dec(J);
           Dec(J);
         end;
         end;
@@ -169,13 +180,14 @@ var
 
 
   procedure QuickSort(L, R : Longint);
   procedure QuickSort(L, R : Longint);
   var
   var
-    I, J : Longint;
+    I, J, PivotIdx : Longint;
     P : Pointer;
     P : Pointer;
   begin
   begin
     repeat
     repeat
       I := L;
       I := L;
       J := R;
       J := R;
-      P := Items + ItemSize*((L + R) div 2);
+      PivotIdx := (L + R) div 2;
+      P := Items + ItemSize*PivotIdx;
       repeat
       repeat
         while Comparer(P, Items + ItemSize*I, Context) > 0 do
         while Comparer(P, Items + ItemSize*I, Context) > 0 do
           Inc(I);
           Inc(I);
@@ -188,10 +200,16 @@ var
             Move((Items + ItemSize*I)^, TempBuf^, ItemSize);
             Move((Items + ItemSize*I)^, TempBuf^, ItemSize);
             Move((Items + ItemSize*J)^, (Items + ItemSize*I)^, ItemSize);
             Move((Items + ItemSize*J)^, (Items + ItemSize*I)^, ItemSize);
             Move(TempBuf^, (Items + ItemSize*J)^, 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;
           end;
           Inc(I);
           Inc(I);
           Dec(J);
           Dec(J);
@@ -232,13 +250,14 @@ procedure QuickSort_ItemList_CustomItemExchanger_Context(
 
 
   procedure QuickSort(L, R : Longint);
   procedure QuickSort(L, R : Longint);
   var
   var
-    I, J : Longint;
+    I, J, PivotIdx : Longint;
     P : Pointer;
     P : Pointer;
   begin
   begin
     repeat
     repeat
       I := L;
       I := L;
       J := R;
       J := R;
-      P := Items + ItemSize*((L + R) div 2);
+      PivotIdx := (L + R) div 2;
+      P := Items + ItemSize*PivotIdx;
       repeat
       repeat
         while Comparer(P, Items + ItemSize*I, Context) > 0 do
         while Comparer(P, Items + ItemSize*I, Context) > 0 do
           Inc(I);
           Inc(I);
@@ -249,10 +268,16 @@ procedure QuickSort_ItemList_CustomItemExchanger_Context(
           if I < J then
           if I < J then
           begin
           begin
             Exchanger(Items + ItemSize*I, Items + ItemSize*J, Context);
             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;
           end;
           Inc(I);
           Inc(I);
           Dec(J);
           Dec(J);