+ 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 -
This commit is contained in:
nickysn 2019-02-04 15:32:41 +00:00
parent b47c58dddc
commit 26486bbaea

View File

@ -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 if PivotIdx = I then
P := Items + ItemSize*J begin
else if P = (Items + ItemSize*J) then PivotIdx := J;
P := Items + ItemSize*I; 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 if PivotIdx = I then
P := Items + ItemSize*J begin
else if P = (Items + ItemSize*J) then PivotIdx := J;
P := Items + ItemSize*I; 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);