Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
6
Добавлен:
28.06.2014
Размер:
39.94 Кб
Скачать

3

 Сортировка естественным слиянием.

Пример:

П

Естественное слияние

44 55’ 12 42 94’ 18’ 06 67  44 55’18’

12 42 94’ 06 67’

12 42 44 55 94’ 06 18 67  12 42 44 55 94’

06 18 67’

06 12 18 42 44 55 67 94

ростое слияние

44 55 12 42 94 18 06 67  44 12 94 06

55 42 18 67

44 55’ 12 42’ 18 94’ 06 67’ 44 55’ 18 94

12 42’ 06 67

12 42 44 55’ 06 18 67 84’  12 42 44 55’

06 18 67 84’

06 12 18 42 44 55 67 94

Метод сортировки, при котором каждый раз сливаются две самые длинные подпоследовательности , называется естественным слиянием .

Назовем серией  самую длинную упорядоченную подпоследовательность.

Пусть исходная последовательность задана в виде файла с. Используются два вспомогательных файла а и b.

Каждый проход состоит из фазы распределения, которая распределяет серии поровну из с в а и b, и фазы слияния которая сливает серии из а и b в с. Сортировка заканчивается, когда число серий будет равно 1.

Рассмотрим алгоритм более подробно.

Пусть l - используется для подсчета числа серий, сливаемых в с.

Определим глобальные объекты:

Type

Item = record

key: integer;

end;

tape = file of item;

Var c: tape

Тогда алгоритм внешней сортировки можно реализовать на языке Стандартный Паскаль следующим образом:

{Сорт. естеств. слиянием }

procedure NaturalMerge;

var l:integer;{Количество серий}

a,b:tape;

begin .

repeat

rewrite(a);

rewrite(b);

reset(c);

Distribute;{распределение}

l:=0; Merge {слияние}

until l=1

end;

Две фазы выражаются двумя

отдельными операторами, которые раскроем в виде процедур.

{ из  с  в  а  и  в }

procedure Distribute;

begin

repeat

Copyrun(c,a);

if not eof(c) then

Copyrun(c,b)

until eof(c);

end ;

{ из  а  и  в  в  с .}

procedure Merge;

begin

repeat

MergeRun; l:=l+1

until not eof(a);

if not eof(a) then

begin

CopyRun(a,c);

l:=l+1

end

end;

Допущение.  Предполагается, что при таком способе распределения в файлах а и b оказывается либо равное число серий, либо в файле а на одну серию больше , чем в b. Эту "лишнюю" серию следует просто переписать.

Эти процедуры используют подчиненные процедуры для обмена одной серии. Они требуют глобальной булевской переменной eor (end of the run), значение которой показывает, достигнут ли конец серии.

{Перепись одной серии из x в y} {Слияние серий из а и b в с}

procedure CopyRun(var x,y:tape); procedure MergeRun;

begin begin

repeat repeat

Copy (x,y) if a^.key<b^.key then

until eor begin

end; Copy (a,c);

if eor then

CopyRun (b,c)

Как только исчерпана одна из end

двух серий, процесс слияния за- else

канчивается. после этого оста- begin

ток другой серии, который еще Copy(b,c);

не исчерпан, пересылается в вы- if eor then

ходную серию путем простого ко- CopyRun(a,c)

пирования: процедура CopyRun. end

until eor

end;

Обе эти процедуры определены с помощью подчиненной процедуры Сopy , которая пересылает элемент из файла x в файл y и определяет, достигнут ли конец серии. Для того, чтобы найти конец серии, нужно сохранять ключ последнего переписанного элемента для сравнения со следующим. Это "заглядывание вперед" достигается использованием буферной переменной файла x^.

{Пересылка элемента из х в y}

procedure Copy (var x,y:tape);

var buf:item;

begin

read(x,buf); write(y,buf);

if eof(x) then

eor:=true

else {Заглядывание вперед}

eor:=buf.key > x^.key

end;

Задание на лабораторную работу 6

Внешняя сортировка”

1. Программу NaturalMerge перевести в Турбо Паскаль, сделав ее работоспособной в Турбо среде

- избавиться от буферной переменной, реализуя “заглядывание вперед”;

- задать внешние имена для файлов;

2. Исправить некорректность программы, вызванную принятым Допущением.

3. Проверить исправленную программу на следующих тестах:

Пример 1 (неправильность допущения).

3 2 5 11'7 13 19 17 23 31 29 37 43 41 47 59 57 61 71 67

Пример 2 (некорректность программы).

17 19 13 57 23 29 11 59 31 37 7 61 41 43 5 67 47 71 2 3

Соседние файлы в папке METOD2