Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Вопрос 45.1. В чем состоит алгоритм внешней сортировки слиянием
Сортировка данных с ленты или диска называется внешней сортировкой. Внешняя сортировка сортирует файлы, которые не помещаются целиком в оперативную память. Если сортируемый файл целиком помещается в память (или целиком помещается в массив, то для него мы используем внутренние методы сортировки. Внешняя сортировка сильно отличается от внутренней. Доступ к файлу является последовательным, а не параллельным как это было в массиве. И поэтому считывать файл можно только блоками и этот блок отсортировать в памяти и снова записать в файл. Принципиальную возможность эффективно отсортировать файл, работая с его частями и не выходя за пределы части, обеспечивает алгоритм слияния. Время внешней сортировки зависит от: · внутренней сортировки частей файла; · многократного считывания и записи данных на диск; · ходов головки между актами считывания/записи; · действий в памяти при слиянии упорядоченных частей Сортировка слиянием Главная идея, которая лежит в основе сортировки слиянием, заключается в том, что мы организуем файл в виде постепенно увеличивающихся серий, т.е. последовательностей записей r1...,rk, где ключ ri не больше, чем ключ ri+1, 1 < i < k. [2] Мы говорим, что файл, состоящий из r1...,rk записей, делится на серии длиной k, если для всех r > 0, таких, что ki < т и rk(i-1)+1, rk(i-1)+2,..., rki является последовательностью длиной k. Если т не делится нацело на k, т.е. т = pk + q, где q < k, тогда последовательность записей rm-q+1, rm-q+2,..., rm, называемая хвостом, представляет собой серию длиной q. Например, последовательность целых чисел, показанная на рис. 1, организована сериями длиной 3. Обратите внимание, что хвост имеет длину, меньшую 3, однако и его записи тоже отсортированы.
Рис. 1. Файл с сериями длиной 3 Главное в сортировке файлов слиянием — начать с двух файлов, например f1 и f2, организованных в виде серий длиной k. Допустим, что: 1) количества серий (включая хвосты) в fi и f2 отличаются не больше, чем на единицу; 2) по крайней мере один из файлов fi или f2, имеет хвост; 3) файл с хвостом имеет не меньше серий, чем другой файл. В этом случае можно использовать достаточно простой процесс чтения по одной серии из файлов f1 и f2, слияние этих серий и присоединения результирующей серии длиной 2k к одному из двух файлов g1 и g2, организованных в виде серий длиной 2k. Переключаясь между g1 и g2, можно добиться того, что эти файлы будут не только организованы в виде серий длиной 2k, но будут также удовлетворять перечисленным выше условиям (1) - (3). Чтобы выяснить, выполняются ли условия (2) и (3), достаточно убедиться в том, что хвост серий fl и f2 слился с последней из созданных серий (или, возможно, уже был ею). Итак, начинаем с разделения всех п записей на два файла f1 и f2, (желательно, чтобы записей в этих файлах было поровну). Можно считать, что любой файл состоит из серий длины 1. Затем мы можем объединить серии длины 1 и распределить их по файлам g1 и g2 , организованным в виде серий длины 2. Мы делаем f1 и f2 пустыми и объединяем g1 и g2 в f1 и f2, которые затем можно организовать в виде серий длины 4. Затем мы объединяем f1 и f2,, создавая g1 и g2, организованные в виде серий длиной 8, и т.д. После выполнения i подобного рода проходов у нас получатся два файла, состоящие из серий длины 2i. Если 2i > п, тогда один из этих двух файлов будет пустым, а другой будет содержать единственную серию длиной п, т.е. будет отсортирован. Так как 2i > п при i > logn, то нетрудно заметить, что в этом случае будет достаточно [log n] + 1 проходов. Каждый проход требует чтения и записи двух файлов, длина каждого из них равна примерно n/2. Общее число блоков, прочитанных или записанных во время одного из проходов, составляет, таким образом, около 2п/b, где b — количество записей, умещающихся в одном блоке. Следовательно, количество операций чтения и записи блоков для всего процесса сортировки равняется О((n log n )/b), или, говоря по-другому, количество операций чтения и записи примерно такое же, какое требуется при выполнении O(log п) проходов по данным, хранящимся в единственном файле. Этот показатель является существенным улучшением в сравнении с О(п) проходами, которые требуются многим из алгоритмов сортировки. В листинге показан код программы сортировки слиянием на языке Pascal. Мы считываем два файла, организованных в виде серий длины k, и записываем два файла, организованных в виде серий длины 2k. Предлагаем читателям, воспользовавшись изложенными выше идеями, самостоятельно разработать алгоритм сортировки файла, состоящего из п записей. В этом алгоритме должна logn раз использоваться процедура merge (слияние), представленная в листинге 1.
Date: 2016-08-30; view: 290; Нарушение авторских прав |