
- •Лекция № 7
- •1. Основные виды сортировки
- •2. Алгоритмы внутренней сортировки
- •Сортировка подсчетом
- •Сортировка простым включением
- •Сортировка методом Шелла
- •Сортировка простым извлечением (выбором).
- •Сортировка методом пузырька (простого обмена)
- •Быстрая сортировка (Хоара)
- •Сортировка слиянием
- •3. Сравнение алгоритмов внутренней сортировки
- •Контрольные вопросы.
Сортировка простым извлечением (выбором).
В этом методе массив также делится на уже отсортированную часть A[i+1], A[i+1], ..., A[n] и еще не отсортированную A[1], A[2], ..., A[i]. Но здесь из неотсортированной части на каждом шаге извлекается максимальный элемент, просматривая ее заново на каждом шаге. Этот элемент будет минимальным элементом отсортированной части, так как все большие его элементы были извлечены на предыдущих шагах, поэтому ставим извлеченный элемент в начало отсортированной части, точнее меняем его с A[i] местами (рис. 4).
Рисунок 4 – Сортировка простым извлечением
Теперь запишем алгоритм.
procedure ExtractSort(n: integer;
var A: array[1..n] of integer);
{Процедура сортировки простым извлечением}
var
i, j, MaxIndex, Tmp: integer;
begin
for i := n downto 2 do begin
{Ищем максимальный элемент в неотсортированной части}
MaxIndex := 1;
for j := 2 to i do
if A[j] > A[MaxIndex] then MaxIndex := j;
{Меняем найденный элемент с первым из отсортированных}
Tmp := A[i]; A[i] := A[MaxIndex];
A[MaxIndex] := Tmp;
end;
end;
Простое извлечение во всех случаях имеет временную сложность, пропорциональную O(n2) (два вложенных цикла, зависящих от n линейно и не зависящих от порядка элементов). Также следует отметить, что данный алгоритм не требует дополнительной памяти и не гарантирует сохранение порядка элементов с одинаковыми значениями.
Сортировка методом пузырька (простого обмена)
Сортировка методом пузырька – один из наиболее широко известных алгоритмов сортировки. В этом методе массив также делится на две части: отсортированную и неотсортированную. На каждом шаге метода осуществляется просмотр от меньших индексов к большим по неотсортированной части, каждый раз сравнивая два соседних элемента. Если они не упорядочены между собой (меньший следует за большим), то меняем их местами. Тем самым за один проход путем последовательных обменов наибольший элемент неотсортированной части сдвинется к ее концу (рис. 5).
Алгоритм называют пузырьковой сортировкой, потому что на каждом шаге наибольший элемент неотсортированной части подобно пузырьку газа в воде всплывает к концу массива.
Заметим, что в том случае, когда за очередной проход не было сделано ни одного обмена, массив уже отсортирован, и следующие проходы можно пропустить. Для отслеживания такой ситуации введем логическую переменную Flag – признак совершения обмена на очередном проходе.
Теперь запишем алгоритм:
procedure BubleSort(n: integer;
var A: array[1..n] of integer);
{Процедура сортировки методом пузырька}
var
i, j, Tmp: integer;
Flag: boolean;
begin
for i := n-1 downto 1 do begin
Flag := false;
for j := 1 to i do
if A[j] > A[j+1] then begin
Tmp := A[j]; A[j] := A[j+1]; A[j+1] := Tmp;
Flag := true;
end;
if not Flag then Break;
end;
end;
Рисунок 5 – Сортировка методом пузырька
Этот алгоритм имеет среднюю и максимальную временные сложности, пропорциональную O(n2) (два вложенных цикла, зависящих от n линейно) и не требует дополнительной памяти. Введение переменной Flag и прерывание работы в случае отсортированного массива позволяет свести минимальную временную сложность к O(n). Также следует отметить, что данный алгоритм не требует дополнительной памяти и сохраняет порядок элементов с одинаковыми значениями.