52704.fb2 Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 70

Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 70

aCompare : TtdCompareFunc;

aTempList : PPointerList);

var

Mid : integer;

is j : integer;

ToInx : integer;

FirstCount : integer;

begin

{вычислить среднюю точку}

Mid := (aFirst + aLast) div 2;

{выполнить сортировку первой половины списка с помощью сортировки слиянием или если количество элементов достаточно мало, при помощи сортировки методом вставок}

if (aFirst < Mid) then

if (Mid-aFirst) <= MSCutOff then

MSInsertionSort(aList, aFirst, Mid, aCompare) else

MS (aList, aFirst, Mid, aCompare, aTempList);

{аналогично выполнить сортировку второй половины}

if (suce(Mid) < aLast) then

if (aLast-succ(Mid) ) <= MSCutOf f then

MSInsertionSort(aList, succ(Mid), aLast, aCompare)

else

MS (aList, suce(Mid), aLast, aCompare, aTempList);

{скопировать первую половину списка во вспомогательный список}

FirstCount := suce (Mid - aFirst);

Move(aList.List^[aFirst], aTempList^[0], FirstCount*sizeof(pointer));

{установить значения индексов: i - индекс для вспомогательного списка (т.е. первой половины списка), j - индекс для второй половины списка, ToInx -индекс в результирующем списке, куда будут копироваться отсортированные элементы}

i := 0;

j := suce (Mid);

ToInx := aFirst;

{выполнить слияние двух списков}

{повторять до тех пор, пока один из списков не опустеет}

while (i < FirstCount) and (j <= aLast) do

begin

{определить элемент с наименьшим значением из следующих элементов в обоих списках и скопировать его; увеличить значение соответствующего индекса}

if ( aCompare( aTempList^[i], aList.List^[j] ) <= 0 ) then begin

aList.List^[ToInx] := aTempList^[i];

inc(i);

end

else begin

aList.List^[ToInx] := aList.List^[ j ];

inc(j);

end;

{в объединенном списке есть еще один элемент}

inc(ToInx);

end;

{если в первом списке остались элементы, скопировать их}

if (i < FirstCount) then

Move(aTempList^[i], aList.List^[ToInx], (FirstCount - i) * sizeof(pointer));

{если во втором списке остались элементы, то они уже находятся в нужных позициях, значит, сортировка завершена; если второй список пуст, сортировка также завершена}

end;

procedure TDMergeSort(aList : TList;