52704.fb2
procedure QSM(aList : TList;
aFirst : integer;
aLast : integer;
aCompare : TtdCompareFunc);
var
L, R : integer;
Pivot : pointer;
Temp : pointer;
begin
while (aFirst < aLast) do
begin
{если в списке есть, по крайней мере, три элемента, выбрать базовый элемент, как медиану первого, последнего и среднего элементов списка и записать его в позицию в середине списка}
if (aLast - aFirst) >= 2 then
begin
R := (aFirst + aLast) div 2;
if (aCompare(aList.List^[aFirst], aList.List^[R]) > 0) then
begin
Temp := aList.List^[aFirst];
aList.List^[aFirst] aList.List^[R];
aList.List^[R] :=Temp;
if (aCompare(aList.List^[aFirst], aList.List^[aLast]) > 0) then
begin
Temp := aList.List^[aFirst];
aList.List^[aFirst] := aList.List^[aLast];
aList.List^[aLast] := Temp;
if (aCompare(aList,List^[R], aList.List^[aLast]) > 0) then
begin
Temp := aList.List^[R];
aList.List^[R] := aList.List^[aLast];
aList.List^[aLast] := Temp;
Pivot :-aList,List^[R];
{в противном случае в списке всего 2 элемента, выбрать в качестве базового первый элемент}
Pivot := aList.List^[ aFirst ];
{задать начальные значения индексов и приступить к разбиению списка}
L := pred( aFirst);
R := succ(aLast);
while true do
begin
repeat
dec (R);
until (aCompare (aList.List^[R], Pivot) <= 0);
repeat
inc(L);
until (aCompare(aList.List^[L], Pivot) >=0);
if (L >=R) then
Break;
Temp := aList.List^[L];
aList.List^[L] := aList.List^[R];
aList.List^[R] := Teilend;