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

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

i, j : integer;

ToInx : integer;

FirstCount : integer;

begin

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

Mid := (aFirst + aLast) div 2;

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

if (aFirst < Mid) then

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

if (suce(Mid) < aLast) then

MSS(aList, succ(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 TDMergeSortStd(aList : TList;

aFirst : integer;

aLast : integer;

aCompare : TtdCompareFunc);

var

TempList : PPointerList;

ItemCount: integer;

begin

TDValidateListRange(aList, aFirst, aLast, 'TDMergeSortStd');

{если есть хотя бы два элемента для сортировки}

if (aFirst < aLast) then begin