
- •Алгоритмическая сложность. Понятие алгоритма. Формы записи. Асимптотический анализ.
- •Линейные структуры данных. Списки. Динамический массив.
- •Линейные структуры данных. Списки. Связный и двусвязный списки.
- •Линейные структуры данных. Очереди. Кольцевые очереди. Стеки. Деки. Алгоритм сортировочной станции.
- •Алгоритм[править | править код]
- •Деревья. Дерево поиска и бинарное дерево поиска. Основные понятия.
- •Сбалансированные деревья. Авл-деревья. Алгоритм добавления нового узла.
- •Сбалансированные деревья. Авл-деревья. Алгоритм удаления существующего узла.
- •21. Сортировка вставками (insertion)
- •25. Сортировка с использованием деревьев. Пирамидальная сортировка (heap-sort).
- •26. Поразрядные, блочные сортировки и сортировка подсчётом.
- •29. Графы. Построение минимального остовного дерева. Алгоритм Прима.
- •28. Графы. Построение минимального остовного дерева. Алгоритм Краскала.
Алгоритмическая сложность. Понятие алгоритма. Формы записи. Асимптотический анализ.
Алгоритм - последовательность команд, предназначенная исполнителю, в результате выполнения которой он должен решить поставленную задачу.
Свойства: конечность, детерминированность, формальность, дискретность, универсальность, эффективность.
Формы записи: словесно-вербальная, графическая (блок-схема), код (псевдокод)
Сложность алгоритма: временная – T(n) и пространственная – S(n)
Временная сложность алгоритма (в худшем случае) — это функция от размера входных данных, равная максимальному количеству элементарных операций, проделываемых алгоритмом для решения экземпляра задачи указанного размера.
По аналогии с временной сложностью, определяют пространственную сложность алгоритма, только здесь говорят не о количестве элементарных операций, а об объёме используемой памяти.
Асимптотический анализ:
Основные оценки роста, встречающиеся в асимптотическом анализе:
Ο (О-большое) – верхняя асимптотическая оценка роста временной функции;
Ω (Омега) – нижняя асимптотическая оценка роста временной функции;
Θ (Тета) – нижняя и верхняя асимптотические оценки роста временной функции.
Пусть n – величина объема данных. Тогда рост функции алгоритма f(n) можно ограничить функций g(n) асимптотически:
Обозначение |
Описание |
f(n) ∈ Ο(g(n)) |
f ограничена сверху функцией g с точностью до постоянного множителя |
f(n) ∈ Ω(g(n)) |
f ограничена снизу функцией g с точностью до постоянного множителя |
f(n) ∈ Θ(g(n)) |
f ограничена снизу и сверху функцией g |
Алгоритмы поиска. Линейный поиск и бинарный поиск.
Бинарный поиск – сложность O(logn)
Линейный поиск – сложность O(n)
Двоичный (или бинарный) поиск является эффективным алгоритмом поиска, выполняется он быстрее чем линейный поиск.
Алгоритм линейного поиска: последовательное сравнение «каждого с каждым» до того момента пока указанный элемент не будет найден.
Его суть заключается в последовательном переборе массива, начиная с первого(нулевого) элемента до тех пор, пока не будет найден нужный элемент.
Алгоритм бинарного поиска:
Определение значения элемента в середине структуры данных. Полученное значение сравнивается с ключом.
Если ключ меньше значения середины, то поиск осуществляется в первой половине элементов, иначе — во второй.
Поиск сводится к тому, что вновь определяется значение серединного элемента в выбранной половине и сравнивается с ключом.
Процесс продолжается до тех пор, пока не будет найден элемент со значением ключа или не станет пустым интервал для поиска.
Поиск подстроки в строке: основные понятия (постановка задачи, алфавит, цепочки). Простой поиск.
Поиск подстроки в строке: постановка задачи
Канонический вариант задачи выглядит так: есть у нас строка A (текст). Необходимо проверить, есть ли в ней подстрока X (образец), и если есть, то где она начинается. То есть именно то, что делает функция strstr() в C. Дополнительно к этому можно еще попросить найти все вхождения образца. Очевидно, что задача имеет смысл только если X не длинее A.
Алфавит:
Строка — это последовательность символов, возможно пустая. Символы, или буквы, принадлежат некоторому множеству, которое называют алфавитом.
Алфавит (англ. alphabet) — конечное непустое множество символов.
Слово (англ. string) или цепочка — конечная последовательность символов некоторого алфавита.
Простой поиск:
I=1, 2. сравнить I-й символ массива T с первым символом массива W, 3. совпадение → сравнить вторые символы и так далее, 4. несовпадение → I:=I+1 и переход на пункт 2, Условие окончания алгоритма: 1. подряд М сравнений удачны, 2. I+M>N, то есть слово не найдено.
Худший случай. Пусть массив T→{AAA….AAAB}, длина │T│=N, образец W→{A….AB}, длина │W│=M. Очевидно, что для обнаружения совпадения в конце строки потребуется произвести порядка N*M сравнений, то есть O(N*M).
Наивный алгоритм поиска подстроки в строке работает за O(n2) в худшем случае — слишком долго
Поиск подстроки в строке: основные понятия (постановка задачи, алфавит, цепочки). Алгоритм Рабина-Карпа
Поиск подстроки в строке: постановка задачи
Канонический вариант задачи выглядит так: есть у нас строка A (текст). Необходимо проверить, есть ли в ней подстрока X (образец), и если есть, то где она начинается. То есть именно то, что делает функция strstr() в C. Дополнительно к этому можно еще попросить найти все вхождения образца. Очевидно, что задача имеет смысл только если X не длинее A.
Алфавит:
Строка — это последовательность символов, возможно пустая. Символы, или буквы, принадлежат некоторому множеству, которое называют алфавитом.
Алфавит (англ. alphabet) — конечное непустое множество символов.
Слово (англ. string) или цепочка — конечная последовательность символов некоторого алфавита.
Алгоритм поиска шаблона, использующий хеширование
алгоритм Рабина — Карпа пытается ускорить проверку эквивалентности образца с подстроками в тексте, используя хеш-функцию. Хеш-функция — это функция, преобразующая каждую строку в числовое значение, называемое хеш-значением (хеш); например, мы можем иметь хеш от строки «hello» равным 5. Алгоритм использует тот факт, что если две строки одинаковы, то и их хеш-значения также одинаковы. Таким образом, всё, что нам нужно, это посчитать хеш-значение искомой подстроки и затем найти подстроку с таким же хеш-значением.
Однако существуют две проблемы, связанные с этим. Первая состоит в том, что, так как существует очень много различных строк, между двумя различными строками может произойти коллизия — совпадение их хешей. В таких случаях необходимо посимвольно проверять совпадение самих подстрок, что занимает достаточно много времени, если данные подстроки имеют большую длину (эту проверку делать не нужно, если ваше приложение допускает ложные срабатывания). При использовании достаточно хороших хеш-функций (смотрите далее) коллизии случаются крайне редко, и в результате среднее время поиска оказывается невелико.
Вторая – пересчитывание хэша. При наивном пересчете затрачивается время O(m) и так как это делается в каждом цикле алгоритм будет затрачивать время тета(m*n) – так делают и простые алгоритмы.
Алгоритм Кнута-Морриса-пратта.
Линейно зависит от объема входящих данных.
Префикс-функция вычисляет длину наибольшего собственного (т.е. не равного самой подстроке) префикса совпадающего с суффиксом этой подстроки.
Для решения задачи поиска подстроки достаточно склеить образец и строку с помощью символа, который не входит в алфавит, напр.: P + ‘#’ + S, после чего начать считать префикс-функцию. Как только значение функции будет равно длине образца, то это будет означать, что подстрока найдена
Бойера-Мура
Строки сравниваются с конца.
Алгоритм сравнивает символы шаблона x справа налево, начиная с самого правого, один за другим с символами исходной строки y. Если символы совпадают, производится сравнение предпоследнего символа шаблона и так до конца. Если все символы шаблона совпали с наложенными символами строки, значит, подстрока найдена, и поиск окончен.
Если же нет, алгоритм использует одну из двух функций для сдвига вправо и продолжения сравнения
Есть два правила сдвига: хорошего суффикса и плохого символа.
Хороший суффикс - если при сравнении текста и шаблона совпало один или больше символов, шаблон сдвигается в зависимости от того, какой суффикс совпал.