- •1. Вычислительные модели. Показатели эффективности алгоритмов, задача анализа алгоритмов. Время выполнения алгоритма для худшего и среднего случая. Вычислительные модели
- •Задача анализа алгоритмов
- •Время работы алгоритма
- •Время выполнения в худшем и среднем случае
- •5. Анализ рекурсивных алгоритмов. Анализ вставки элемента в бинарное дерево поиска.
- •5.Анализ сложности рекурсивных алгоритмов
- •6. Связные списки: однонаправленные, двунаправленные, кольцевые. Примеры реализации.
- •Однонаправленные (односвязные) списки
- •Двунаправленные (двусвязные) списки
- •7. Структура данных "стек". Реализация с помощью массива и связного списка, смешанная реализация. Пример использования (кроме задачи о скобках)
- •8.Структура данных "очередь". Реализация с помощью массива, циклического массива, односвязного списка.
- •Очереди
- •Бинарные деревья
- •11. Обходы бинарных деревьев (клп - "Корень-Левое-Правое" ,лкп,лпк) с примерами программной реализации.
- •12. Удаление элемента из бинарного дерева поиска.
- •13.Рандомизированные деревья. Вставка элемента в рандомизированное бинарное дерево поиска.
- •Включение элемента в рандомизированное дерево
- •Рекурсивный алгоритм вставки в рандомизированное дерево:
- •14.Быстрая сортировка Хоара (QuickSort)
- •Краткое описание алгоритма
- •Алгоритм
- •Оценка эффективности
- •15. Сортировка слиянием (MergeSort)
- •16.Полный перебор подмножеств
- •17. Полный перебор перестановок
- •18. Перебор с возвратом и отсечением вариантов
- •3.1 Использование рекурсии для записи алгоритма
- •3.2 Примеры решения задач при помощи перебора с возвратом
- •.1 Отсечение лишних вариантов
- •19. Динамическое программирование. Разбиение задачи на подзадачи, принцип оптимальности. Задача о маршруте из верхнего угла таблицы в нижний
- •20. Пример использования динамического программирования для подсчета количеств комбинаторных объектов - найти количество разбиений числа на слагаемые
- •21. Жадные алгоритмы. Принцип жадного выбора, свойство оптимальности для подзадач, схема доказательства корректности жадного алгоритма. Задача о заявках.
- •Принцип жадного выбора
- •Оптимальность для подзадач
- •Примеры Размен монет
- •Выбор заявок
- •22. Хеширование с цепочками. Эффективность хеширования с цепочками. Хеш-функции, качество хеш-функций, подходы к построению хеш-функций.
- •23. Хеширование с открытой адресацией. Способы разрешения коллизий. Анализ эффективности.
Бинарные деревья
Хотя деревья общего вида достаточно важны, мы сосредоточимся на ограниченном классе деревьев, где каждый родитель имеет не более двух сыновей (Рис. 5). Такие бинарные деревья (binary trees) имеют унифицированную структуру, допускающую разнообразные алгоритмы прохождения и эффективный доступ к элементам. Изучение бинарных деревьев дает возможность решать наиболее общие задачи, связанные с деревьями, поскольку любое дерево общего вида можно представить эквивалентным ему бинарным деревом.
У каждого узла бинарного дерева может быть 0, 1 или 2 сына. По отношению к узлу слева будем употреблять термин левый сын (left child), а по отношению к узлу справа – правый сын (right child). Наименования "левый" и "правый" относятся к графическому представлению дерева. Бинарное дерево является рекурсивной структурой. Каждый узел – это корень своего собственного поддерева. У него есть сыновья, которые сами являются корнями деревьев, называемых левым и правым поддеревьями соответственно. Таким образом, процедуры обработки деревьев рекурсивны. Вот рекурсивное определение бинарного дерева:
Бинарное дерево - это такое множество узлов B, что
а) B является деревом, если множество узлов пусто (пустое дерево – тоже дерево);
б) B разбивается на три непересекающихся подмножества:
{R} корневой узел
{L1, L2, ..., Lm} левое поддерево R
{R1, R2, ..., Rm} правое поддерево R
На любом уровне n бинарное дерево может содержать от 1 до 2n узлов. Число узлов, приходящееся на уровень, является показателем плотности дерева. Интуитивно плотность есть мера величины дерева (число узлов) по отношению к глубине дерева. На Рис. 5 дерево А содержит 8 узлов при глубине 3, в то время как дерево B содержит 5 узлов при глубине 4. Последний случай является особой формой, называемой вырожденным (degenerate) деревом, у которого есть единственный лист (E) и каждый нелистовой узел имеет только одного сына. Вырожденное дерево эквивалентно связанному списку.
Рис.5. Бинарные деревья
Деревья с большой плотностью очень важны в качестве структур данных, так как они содержат пропорционально больше элементов вблизи корня, т.е. с более короткими путями от корня. Плотное дерево позволяет хранить большие коллекции данных и осуществлять эффективный доступ к элементам. Быстрый поиск – главное, что обусловливает использование деревьев для хранения данных.
Вырожденные деревья являются крайней мерой плотности. Другая крайность – законченные бинарные деревья (complete binary tree) глубины N, где каждый уровень 0...N - 1 имеет полный набор узлов, и все листья уровня N расположены слева. Законченное бинарное дерево, содержащее 2N узлов на уровне N, является полным. На Рис. 6 показаны законченное и полное бинарные деревья.
Законченные и полные бинарные деревья дают интересные математические факты. На нулевом уровне имеется 20 узлов, на первом — 21, на втором — 22 и т.д. На первых k-1 уровнях имеется 2k-1 узлов.
1 + 2 + 4 + ... + 2k-1 = 2k-1
На уровне k количество дополнительных узлов колеблется от 1 до 2k (полное). В полном дереве число узлов равно
1 + 2 + 4 + ... + 2k-1 + 2k = 2k-1 - 1
Число узлов законченного бинарного дерева удовлетворяет неравенству
2k < N < 2k-1 - 1 < 2k-1
Решая его относительно k, имеем
k < log2 (N) < k+1
Например, полное дерево глубины 3 имеет
24 - 1 = 15 узлов
Рис.6. Классификация бинарных деревьев