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

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

Начнем решение задачи с обсуждения того, как можно упорядочить карточки с именами, расположенные на столе. Пусть у нас есть список имен:

Егор

Аня

Гриша

Боря

Вера

Обратите внимание на то, что подсписок, состоящий только из первого имени Егор, уже упорядочен, а подсписок, состоящий из первых двух имен, Егор и Аня, — не упорядочен. Следовательно, нужно взять карточку с именем Аня, опустить, карточку с именем Егор на место, где находилась карточка Аня, и затем поместить имя Аня в пустую позицию вверху списка (как показано в первом ряду рис. 4.6). На этом этапе наш список будет таким:

Аня

Егор

Гриша

Боря

Вера

Теперь два первых имени образуют упорядоченный список, а первые три — нет. Следовательно, мы должны взять карточку с третьим именем, Гриша, опустить карточку с именем Егор на место, где находилось имя Гриша, а затем поместить имя Гриша в пустую позицию, как показано во втором ряду рис. 4.6. Теперь упорядочены первые три элемента списка. Взяв карточку с четвертым именем, Боря, опустив имена Егор и Гриша вниз и вставив имя Боря в полученный промежуток, мы получим список, в котором упорядочены первые четыре элемента (третий ряд рис. 4.6). И, наконец, мы завершаем процесс сортировки: выбираем имя Вера, опускаем имена Егор и Гриша на одну позицию вниз и вставляем имя Вера в промежуток между карточками.

Проанализировав процесс сортировки отдельного списка, мы должны обобщить его, чтобы получить алгоритм сортировки любого списка. Можно заметить, что каждый ряд, изображенный на рис. 4.6, отображает один и тот же общий процесс: выбрать первое имя неупорядоченной части списка, переместить имена, которые больше выбранного имени, вниз и поместить данное имя в образовавшуюся пустую позицию. Если мы определим выбранное имя как ведущий элемент (pivot entry), то этот процесс можно записать следующим образом:

Временно переместить ведущий элемент в другое место, оставив одну позицию Список пустой; while (есть имя над пустой позицией, и оно больше ведущего элемента) do

(переместить имя, находящееся над пустой позицией, в эту пустую позицию.

оставив пустой позицию над этим элементом) Переместить ведущий элемент в пустую позицию Список.

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

N <- 2;

while (значение N не превышает длину Список) do (назначить N-й элемент Список ведущим;

N <- N + 1)

где выражение «длина списка» обозначает число элементов в списке, а точки

указывают расположение описанной выше процедуры.

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

Листинг 4.2. Алгоритм сортировки методом вставки, записанный с помощью псевдокода

procedure Сортировка (Список)

N <- 2;

while (значение N не превышает длину Список) do

(назначить N-й элемент Список ведущим:

Временно переместить ведущий элемент в другое место, оставив одну позицию Список пустой:

while (есть имя над пустой позицией, и это имя больше ведущего элемента) do

(переместить имя, находящееся над пустой позицией, в эту пустую позицию, оставив пустой позицию над этим элементом)

Переместить ведущий элемент в пустую позицию Список:

N <- N + 1)

Обратите внимание на то, что структура программы (см. листинг 4.2) представляет собой цикл, помещенный в цикл. Внешний цикл описывается первым оператором while, а внутренний — вторым. Выполнение тела внешнего цикла приводит к инициализации и выполнению внутреннего цикла до тех пор, пока его условие завершения не будет истинно. Следовательно, однократное выполнение внешнего цикла приведет к тому, что тело внутреннего цикла будет выполнено несколько раз.

Во время выполнения шага инициализации внешнего цикла устанавливается исходное значение переменной N: N «-2

В процессе выполнения шага модификации увеличивается значение переменной N в конце тела цикла: N «-N +1

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

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: