02 сортировка и поиск
DESCRIPTION
Слайды лекции спецкурса "Олимпиадное программирование".TRANSCRIPT
![Page 1: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/1.jpg)
Сортировка и поиск
Федор ЦаревСпецкурс «Олимпиадное
программирование»Лекция 2
22.12.2008Санкт-Петербург, Гимназия 261
![Page 2: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/2.jpg)
Цель лекции
Изучить алгоритмы сортировки и поиска Изучить методы их реализации на языке
программирования Pascal (Delphi)
![Page 3: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/3.jpg)
Зачем это надо?
Сортировка и поиск в разных вариантах используются практически во всех программах: от поиска слова в файле до поиска в Интернете
![Page 4: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/4.jpg)
Задача сортировки
Задан набор объектов a1, a2, …, an Необходимо их переставить так, чтобы
они шли в неубывающем порядке Два варианта:
объекты можно только сравнивать есть доступ к их внутренней структуре
![Page 5: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/5.jpg)
Обмен двух переменных
Операция, с помощью которой осуществляется сортировка
procedure swap(var a, b : integer);vart : integer;
begint := a;a := b;b := t;
end;
![Page 6: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/6.jpg)
Без дополнительной переменной (1)
Можете придумать?
С помощью сложения и вычитания
a := a + b; // a = a + b; b = b;b := a - b; // a = a + b; b = a;a := a - b; // a = b; b = a;
![Page 7: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/7.jpg)
Без дополнительной переменной (2)
С помощью операции xor (исключающее ИЛИ)
a := a xor b; // a = a xor b; b = b;b := a xor b; // a = a xor b; b = a;a := a xor b; // a = b; b = a;
Методы без дополнительной переменной обладают существенным недостатком.
Каким?
![Page 8: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/8.jpg)
Сортировка выбором
На каждом шаге выбирается минимальный из еще не просмотренных элементов
Это повторяется (n-1) раз
min
![Page 9: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/9.jpg)
Программа
for i := 1 to n – 1 do beginminpos := i;for j := i + 1 to n do begin
if (a[j] < a[minpos]) then begin
minpos := j;end;
end;swap(a[i], a[minpos]);
end;
![Page 10: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/10.jpg)
Оценка алгоритма
Время работы – O(n2) Число сравнений – O(n2) Число обменов – O(n) Дополнительная память – O(1)
![Page 11: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/11.jpg)
Сортировка вставками
Очередной элемент вставляется в уже отсортированную часть массива на соответствующее место
![Page 12: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/12.jpg)
Программа (1)for i := 1 to n do beginpos := -1;if (a[i] < a[1]) then begin
pos := 1;end;for j := i - 1 downto 1 do begin
if (a[j] < a[i]) then beginpos := j + 1;break;
end;end;// pos – позиция, на которой должен // оказаться a[i]
![Page 13: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/13.jpg)
Программа (2)// Сдвиг элементов с a[pos] до a[i-1] вправо на одну позициюt := a[i];for j := i - 1 downto pos do begin
a[j + 1] := a[j];end;a[pos] := t;
end;
![Page 14: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/14.jpg)
Оценка алгоритма
Время работы – O(n2) Число сравнений – O(n2) (можно улучшить
до O(nlogn)) Число обменов – O(n2) Дополнительная память – O(1)
![Page 15: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/15.jpg)
Сортировка пузырьком
Если два соседних элемента расположены в неправильном порядке, то их надо поменять местами
Сделаем n-1 проход, на каждом из которых будем проверять все пары соседних элементов
Элементы будут двигаться к своим местам как пузырьки
![Page 16: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/16.jpg)
Демонстрация
С сайта ru.wikipedia.org
![Page 17: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/17.jpg)
Программа
for i := n downto 2 do beginfor j := 1 to i – 1 do begin
if (a[j] > a[j + 1]) then begin
swap(a[j], a[j + 1]);end;
end;end;
![Page 18: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/18.jpg)
Оценка алгоритма
Время работы – O(n2) Число сравнений – O(n2) Число обменов – O(n2) Дополнительная память – O(1) Сравнивает только соседние элементы Наиболее прост в реализации
![Page 19: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/19.jpg)
Сортировка слиянием
Сортировка слиянием предложена Джоном фон Нейманом в 1946 году
Джон фон Нейман – венгро-американский математик, сделавший важный вклад в квантовую физику, квантовую логику, функциональный анализ, теорию множеств, информатику, экономику и другие отрасли науки
![Page 20: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/20.jpg)
Метод «разделяй-и-властвуй»
Один из основных методов построения алгоритмов
Сложные задачи надо решать, разбивая их на более простые
Отсортировать массив можно так: разбить его на две половины отсортировать каждую из них объединить отсортированные массивы
![Page 21: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/21.jpg)
Дерево сортировки слиянием
n
n/2 n/2
n/4 n/4 n/4 n/4
...
1 1 1 1 1 1 1 1
H =
log
n
n
![Page 22: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/22.jpg)
Слияние массивов (1)
Даны два упорядоченных по возрастанию массива: a[1..n] и b[1..m]
Необходимо построить упорядоченный массив c[1..n+m], содержащий эти же элементы
Число действий должно быть порядка n+m
![Page 23: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/23.jpg)
Слияние массивов (2)
На каждом шаге выбираем минимальный из первых непросмотренных элементов массивов
Надо хранить их номера: pa, pb
a
b
c
min
![Page 24: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/24.jpg)
Слияние массивов – программа (1)
pa := 1;pb := 1;pc := 1;while ((pa <= n) and (pb <= m)) do beginif (pa <= n) then begin
min := a[pa];end;if (pb <= m) and ((b[pb] < min) or (pa > n)) then begin
min := b[pb];end;
![Page 25: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/25.jpg)
Слияние массивов – программа (2)if (pa <= n) and (min = a[pa]) then begin
c[pc] := a[pa];inc(pc);inc(pa);continue;
end;if (pb <= m) and (min = b[pb]) then begin
c[pc] := b[pb];inc(pc);inc(pb);continue;
end;end;
![Page 26: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/26.jpg)
И, наконец…
procedure mergeSort(l, r : integer);beginif (l >= r) then begin
exit;end;m := (l + r) div 2;mergeSort(l, m);mergeSort(m + 1, r); // m плюс один// Слияние частей массива a: a[l..m] и a[m + 1..r] – напишите сами
end;
![Page 27: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/27.jpg)
Оценка времени работы
Время работы – O(nlogn) Число сравнений – O(nlogn) Число обменов – O(nlogn) Дополнительная память – O(n)
![Page 28: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/28.jpg)
Быстрая сортировка
Предложена Чарльзом Хоаром в 1964 году Основана на методе «разделяй-и-
властвуй»
![Page 29: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/29.jpg)
Идея алгоритма
Выберем в массиве разделяющий элемент X Переставим элементы в массиве так, чтобы сначала
шли меньшие X (первая часть), затем равные (вторая часть), а в конце – большие (третья часть)
Осталось отсортировать первую и третью части массива
![Page 30: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/30.jpg)
Демонстрация работы
С сайта ru.wikipedia.org
![Page 31: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/31.jpg)
Дерево в лучшем случаеn
n/2 n/2
n/4 n/4 n/4 n/4
...
1 1 1 1 1 1 1 1
H =
log
n
n
![Page 32: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/32.jpg)
Дерево в худшем случае
n
n - 1 1
H =
n
n
n - 2 1
...11
![Page 33: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/33.jpg)
Программаprocedure qsort(l, r : integer);var
m, i, j : integer;begin
m := a[l + random(r – l + 1)];i := l;j := r;while (i <= j) do begin
while (a[i] < m) do inc(i);while (a[j] > m) do dec(j);if (i <= j) then begin
swap(a[i], a[j]);inc(i);dec(j);
end;end;if (l < j) then qsort(l, j);if (i < r) then qsort(i, r);
end;
![Page 34: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/34.jpg)
Упражнения
Постройте массивы, на которых будет достигаться квадратичное время работы алгоритма с выбором разделяющего элемента без использования рандомизации: m := a[l]; m := a[r]; m := a[(l + r) div 2];
![Page 35: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/35.jpg)
Оценка времени работы
Время работы – в среднем O(nlogn), в худшем случае O(n2)
Число сравнений – в среднем O(nlogn), в худшем случае O(n2)
Число обменов – в среднем O(nlogn), в худшем случае O(n2)
Дополнительная память – O(1) Наиболее быстрый на практике алгоритм
– при условии использования рандомизации
![Page 36: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/36.jpg)
Сортировка с помощью кучи
Использует особую структуру данных – кучу (heap)
Будет рассмотрена в одной из следующих лекций
Также обладает временем работы O(nlogn)
![Page 37: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/37.jpg)
Устойчивость сортировки
Алгоритм сортировки устойчив, если в упорядоченном массиве порядок элементов с одинаковыми ключами такой же, как в исходном
Упражнение. Проанализируйте изученные алгоритмы сортировки на устойчивость
Упражнение. Придумайте способ сделать любой алгоритм сортировки устойчивым
![Page 38: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/38.jpg)
Упражнение
Написать программу, визуализирующую работу алгоритмов сортировки
![Page 39: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/39.jpg)
Задача поиска
Задан набор объектов a1, a2, …, an Задан объект X Необходимо проверить, присутствует ли
он в указанном наборе Два варианта:
объекты можно только сравнивать есть доступ к их внутренней структуре
![Page 40: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/40.jpg)
Линейный поиск
found := false;for i := 1 to n do beginif (a[i] = x) then begin
found := true;break;
end;end; Время работы – O(n)
![Page 41: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/41.jpg)
Двоичный поиск
Пусть исходный набор уже отсортирован Сравним X со средним элементом a[n/2]
набора В зависимости от результата перейдем
либо к левой половине, либо к правой Размер рассматриваемой части на каждом
шаге будет сокращать вдвое Время работы будет O(logn)
![Page 42: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/42.jpg)
Инвариант цикла
Логическое выражение, которое истинно непосредственно перед началом выполнения
цикла после выполнения каждой его итерации сразу после окончания выполнения цикла
![Page 43: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/43.jpg)
Инвариант для двоичного поиска
Задан массив a[1] ≤ a[2] ≤ … ≤ a[n] Задано искомое число x Границы текущего отрезка поиска: left и
right Инвариант цикла: a[left] ≤ x < a[right]
![Page 44: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/44.jpg)
Программаfunction binsearch(x : integer) : integer;begin
result := -1; // Не найденоif (a[1] > x) then begin
exit;end;left := 1;right := n + 1;while (right – left > 1) do begin
mid := left + (right - left) / 2;if (a[mid] > x) then begin // Вспомните
right := mid; // инвариантend else begin // цикла!
left := mid;end;
end;if (a[left] = x) then begin
result := left; // Вспомните инвариант цикла!end;
end;
![Page 45: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/45.jpg)
Двоичный поиск
left right
left
right
После окончания цикла
Перед началом цикла
![Page 46: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/46.jpg)
Упражнения
Пусть в массиве несколько элементов равны x. Какой из них будет найден?
Как найти число элементов, равных X, в заданном упорядоченном массиве за время O(logn)?
Модифицируйте сортировку вставками так, чтобы в ней выполнялось O(nlogn) сравнений.
![Page 47: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/47.jpg)
Другие варианты поиска
Поиск подстроки в строке Поиск строки в множестве строк Двоичные деревья поиска Хэш-таблицы …
Все это будет рассмотрено в следующих лекциях!
![Page 48: 02 сортировка и поиск](https://reader036.vdocuments.site/reader036/viewer/2022062514/558c96c9d8b42af0248b472d/html5/thumbnails/48.jpg)
Выводы
Алгоритм быстрой сортировки является наиболее быстрым на практике алгоритмом сортировки (при использовании случайного выбора разделяющего элемента)
С помощью двоичного поиска можно быстро искать в упорядоченном массиве
Существует множество методов поиска, которые будут рассмотрены в следующих лекциях