Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка эффективных алгоритмов.doc
Скачиваний:
115
Добавлен:
24.11.2019
Размер:
1.2 Mб
Скачать

2.4. Вопросы для самоконтроля

        1. Алгоритм последовательного поиска. Оценка худшего, лучшего и среднего случая.

        2. Алгоритм двоичного поиска. Оценка среднего случая.

        3. Выборка k-го по величине значения.

        4. Рекурсивный алгоритм выборки k-го по величине значения.

3.Алгоритмы сортировки

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

Все изучаемые алгоритмы будут сортировать список в порядке возрастания ключа (хотя, если поменять знак ”>” на ”<”, то список окажется отсортированным в порядке убывания.)

3.1. Сортировка трех чисел по месту

На вход поступают три числа. Алгоритм, производящий сортировку, выглядит следующим образом:

SortABC1(a,b,c)

If a>b then // обмен a и b

ta; ab; bt

endif

If b>c then // обмен b и c

tb; bc; ct

endif

If a>b then // обмен a и b

ta; ab; bt

endif

end

Для этого алгоритма fА1 =12 (набор 3,2,1), fА1 =3 (набор 1,2,3). В среднем случае получаем  fА1-=3+3* +3* +3* =7 .

Допустим, на вход поступают числа 1,2,3. Распишем все возможные комбинации, в которых могут прийти эти числа: (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2), (3,2,1).

Очевидно, что эти тройки чисел можно разделить на две группы, в одной из которых a>b, в другой a<b. Анализируя их, получаем алгоритм 2:

SortABC2(a,b,c)

If a>b then

If b>c then //ситуация 321, обмен 3 и 1 местами

ta; ac; ct

else

if a>c then // ситуация 312

ta; ab; bc; ct

else // ситуация 213, обмен 2 и 1 местами

ta; ab; bt

endif

endif

else

If b>c then

If a>c then // ситуация 231

tc; cb; ba; at

else // ситуация 132, обмен 3 и 2

tb; bc; ct

end if

else // ситуация 123

exit.

endif

endif

end

Вероятности появления любой комбинации равны между собой, и составляют 1/6. Оценки трудоемкости этого алгоритма соответственно равны:

в лучшем случае fА2 =2, в худшем - fА2=7, в среднем  fА2=5 .

3.2. Сортировка вставками

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

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

InsertSort (list, N)

// list - сортируемый список

// N - число элементов

for i = 2 to N do

new  list [i]

m  i – 1

While (m  1) and ( list [m] > new) do

// сдвигаем все элементы, большие очередного

list [m + 1]  list [m]

m  m – 1

endwhile

list [m + 1]  new

endfor

end

Этот алгоритм заносит новое вставляемое значение в переменную new. Затем он освобождает место для этого нового элемента, сдвигая (в цикле while) все большие элементы на одну позицию вправо. Последняя итерация переносит элемент с номером m+1 в позицию (m+2). Это означает, что позиция (m+1) освобождается для «нового элемента».

Анализ наихудшего случая - видно, что наибольшее число операций в цикле while выполняется в случае, если вновь добавляемый элемент меньше всех элементов, содержащихся в уже отсортированной части списка. В этой ситуации выполнение цикла завершается, когда значение m равно 0.

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

Как ведется обработка такого списка?

Первым вставляем второй элемент. Он сравнивается с одним элементом, второй вставленный элемент (третий по порядку) сравнивается с двумя предыдущими, а третий вставляемый элемент – с тремя предыдущими и т.д. (следовательно i – ый с i предыдущими), и этот процесс повторяется (N – 1) раз.

Общее число проходов цикла while может быть вычислено следующим образом:

fА(N) = =

Следовательно, асимптотически fА1(N) = O (N2/2).

В среднем случае необходимое количество сравнений определяется половиной длины текущей отсортированной части списка, что дает оценку

fА(N) = O(N2/4).

Пример 3.1 Сортировка методом вставки

(7 3 9 4 2 5 6 1 8) -- исходный список

На первом шаге отсортированный список состоит из одного элемента (7).

На следующем шаге в этот отсортированный список добавляется новый элемент (3). Его значение сравнивается с последним элементом в отсортированной части (3<7), следовательно, значение 7 надо сдвинуть вправо, дав возможность разместить на месте 3. После второго шага (сравнений 1, сдвиг 1) список имеет вид: (3 7 9 4 2 5 6 1 8). (Жирным начертанием выделена отсортированная часть списка).

На третьем шаге в отсортированный двухэлементный список добавляется новый элемент (9). Его значение не меньше последнего элемента, следовательно, он добавляется в конец списка (сравнений 1, сдвига нет). Список имеет вид:

  1. 7 9 4 2 5 6 1 8)

На следующем шаге добавление 4 приведет к сдвигу двух элементов (7 и 9), при этом будет выполнено 3 сравнения. Вид списка: (3 4 7 9 2 5 6 1 8).

Далее процесс повторяется. Общее число операций для этого списка будет: сравнений - 26, сдвига - 19.