Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Комплект Информатика / Курс лекций.doc
Скачиваний:
128
Добавлен:
22.05.2015
Размер:
4.8 Mб
Скачать

3 Алгоритм сортировки методом вставки

В качестве дополнительного примера итеративной структуры рассмотрим задачу сортировки списка имен в алфавитном порядке. Прежде чем приступить к обсуждению, следует установить некоторые ограничения, которые необходимо будет учитывать. Попросту говоря, наша задача — отсортировать список "внутри его самого". Другими словами, мы хотим отсортировать список, просто переставляя его элементы, а не перемещая весь список в другое место. Это аналогично сортировке списка, элементы которого записаны на отдельных карточках, разложенных на переполненном рабочем столе. На столе достаточно места для всех карточек, однако запрещается отодвигать другие находящиеся на столе материалы, чтобы освободить дополнительное пространство. Подобное ограничение типично для компьютерных приложений, но не потому, что рабочее пространство в машине обязательно переполнено, как наш рабочий стол, а потому, что мы стремимся использовать доступный объем памяти самым эффективным образом. Попробуем сделать первый шаг в поисках решения задачи. Рассмотрим, как можно было бы отсортировать карточки с именами, расположенные на рабочем столе. Пусть исходный список имен выглядит следующим образом:

Fred

Alice

David

Bill

Carol

Один из подходов к сортировке этого списка заключается в следующем. Обратите внимание, что подсписок, состоящий из единственного верхнего имени Fred, уже отсортирован, а подсписок из двух верхних имен, Fred и Alice, — еще нет. Поэтому подымем карточку с именем Alice, поместим карточку с именем Fred вниз, туда, где раньше была карточка с именем Alice, а затем положим карточку с именем Alice в самое верхнее положение, как показано в первой строке на рис. 4.10. Теперь список будет иметь такой вид:

Alice

Fred

David

Bill

Carol

В этом варианте два верхних имени образуют отсортированный подсписок, а три верхних — нет. Подымем третью карточку с именем David, опустим карточку с именем Fred вниз, туда, где только что была карточка с именем David, а затем поместим карточку с именем David в ту позицию, которую раньше занимала карточка с именем Fred, как показано во второй строке на рис.5. Теперь три верхних элемента списка образуют отсортированный подсписок. Продолжая действовать таким способом, мы можем получить список, в котором будут отсортированы четыре верхних элемента. Для этого нужно поднять четвертую карточку с именем Bill, опустить вниз карточки с именами Fred и David, а затем поместим карточку с именем Bill в освободившуюся позицию (третья строка на рис. 5). И, наконец, чтобы завершить процесс сортировки, необходимо поднять карточку с именем Carol, опустить вниз карточки с именами Fred и David, а затем поместить карточку с именем Carol в освободившуюся позицию — как показано в четвертой строке на рис.5.

Теперь наша задача состоит в том, чтобы проанализировать процесс сортировки конкретного списка и попытаться обобщить его в целях получения алгоритма сортировки любого списка. С этой точки зрения каждая строка на рис. 5 представляет собой один и тот же повторяющийся процесс: «Поднять карточку с именем, первую в неотсортированной части списка, сдвинуть вниз карточки с именами, которые находятся ниже по алфавиту, чем имя на взятой нами карточке, а затем поместить эту взятую карточку на освободившееся место в списке». Если

Рисунок 5 - Сортировка списка имен Fred, Alice, David, Bill и Carol

назвать выбранное имя опорным элементом, то с помощью нашего псевдокода данный процесс можно описать следующим образом:

Переместить ОпорныйЭлемент во временное хранилище, оставив в списке пустое место;

while (над пустым местом есть имя, и оно > ОпорныйЭлемент) do {переместить имя, находящееся над пустым местом, вниз, оставив в его прежней позиции пустое место}Поместить ОпорныйЭлемент на пустое место в списке

Обратите внимание, что этот процесс должен выполняться многократно. Чтобы начать процедуру сортировки, в качестве опорного элемента должен быть выбран второй элемент списка. Затем, перед каждым последующим выполнением описанной процедуры, должен выбираться новый опорный элемент, находящийся на одну позицию ниже предыдущего, и так до тех пор, пока не будет достигнут конец списка, т.е. положение опорного элемента должно перемещаться от второго элемента к третьему, затем к четвертому и т.д. Следуя этому, мы можем организовать требуемое управление путем повторения процедуры с помощью следующей последовательности инструкций:

N ← 2;

while (N ≤ ДлинаСписка) do

{выбрать N-й элемент как ОпорныйЭлемент; N ← N + 1}

Здесь N — счетчик, параметр ДлинаСписка — количество элементов в списке, а точки указывают место, где должна располагаться составленная нами выше процедура.

Полный текст программы сортировки на языке псевдокода приведен на рис. 6. Не вдаваясь в подробности, можно сказать, что эта программа сортирует список, многократно повторяя следующие действия: "Элемент извлекается из списка, а затем вставляется на надлежащее ему место". Именно по причине многократного повторения вставки элементов в список данный алгоритм получил название сортировки методом вставки (insertion sort).

Обратите внимание, что представленная на рис. 6 структура содержит Цикл, помещенный внутрь другого цикла. Внешний цикл представлен первой инструкцией while, а внутренний цикл — второй инструкцией while. Каждое выполнение тела внешнего цикла приводит к тому, что внутренний цикл инициализируется и выполняется до тех пор, пока не будет выполнено условие его окончания. Таким образом, однократное выполнение тела внешнего цикла будет сопровождаться многократным выполнением тела внутреннего цикла.

Рисунок 6 - Алгоритм сортировки методом вставки, написанный на псевдокоде

При инициализации управления внешним циклом начальное значение счетчика N устанавливается с помощью инструкции

N ← 2;

Операция модификации этого цикла включает увеличение значения счетчика N в конце тела цикла с помощью инструкции

N ← N + 1.

Условие окончания внешнего цикла выполняется, когда значение счетчика N превысит длину сортируемого списка.

Управление внутренним циклом инициализируется, когда опорный элемент извлекается из списка и в нем образуется пустое место. Операция модификации включает перемещение расположенных выше элементов на пустое место вниз, в результате чего свободное место перемещается вверх по списку. Условие окончания выполняется, когда пустое место или находится непосредственно под именем, которое по алфавиту размещается выше опорного значения, или же достигает верхней позиции списка.