Двоичные деревья поиска. Очередь с приоритетами Федор Царев Спецкурс «Олимпиадное программирование» Лекция 3 19.01.2009, 26.01.2009 Санкт-Петербург, Гимназия.

Презентация:



Advertisements
Похожие презентации
Задание бинарных деревьев с помощью массивов Обходы деревьев.
Advertisements

Динамическое программирование. Основные концепции Федор Царев, Андрей Лушников Спецкурс «Олимпиадное программирование» Лекция Санкт-Петербург,
Дерево это связный ациклический граф. Связность означает наличие путей между любой парой вершин, ацикличность отсутствие циклов и то, что между парами.
Поиск информации Задача поиска: где в заданной совокупности данных находится элемент, обладающий заданным свойством? Большинство задач поиска сводится.
1 Программирование на языке Паскаль Тема 4. Сортировка массивов.
К.Ю. Поляков, Е.А. Ерёмин, 2013 Программирование на языке Паскаль § 64. Сортировка 1.
Деревья1 Структуры и алгоритмы обработки данных, 1 Лекция 6 ДЕРЕВЬЯ (продолжение) 1.Нерекурсивные процедуры обхода бинарных деревьев 2.Представления.
Задача Заполнить одномерный целочисленный массив, состоящий из 15 элементов, случайными числами (диапазон задайте сами). Вывести его на экран. Отсортировать.
Алгоритмы сортировки. 2 Сортировка Сортировка – это расстановка элементов массива в заданном порядке (по возрастанию, убыванию, последней цифре, сумме.
Реализация списков:динамические структуры ListList clasclas структура одного элемента type LIST = celltype; celltype = record element: eltype; next: LIST.
Обменные сортировки:BubbleSort Алгоритм прямого обмена основывается на сравнении и смене позиций пары соседних элементов. Процесс продолжается до тех пор.
Задачи с использованием одномерных массивов 1. Опишите алгоритм подсчёта среднего значения положительных элементов в целочисленном массиве из 30 элементов.
Задачи с использованием одномерных массивов 1. Опишите алгоритм подсчёта среднего значения положительных элементов в целочисленном массиве из 30 элементов.
Сортировка методом пузырька, выбором (Pascal) Кокарева Светлана Ивановна.
О БРАБОТКА МАССИВОВ 1. Включение элемента в заданную позицию массива 2. Удаление элементов массива. Удаление элементов массива. Удаление элементов массива.
САОД кафедра ОСУ 1 Основные абстрактные типы данных Схема процесса создания программ для решения прикладных задач ВУ.
Списки Динамические структуры данных. 2 Строение: набор узлов, объединенных с помощью ссылок. Как устроен узел: данные ссылки на другие узлы Типы структур:
1 Программирование на языке Паскаль Часть II Тема 4. Сортировка массивов © К.Ю. Поляков,
Массивы 9 класс. Основные теоретические сведения Примеры решения задач.
Б-деревья Лекция 19. Б-деревья Б-деревья – сбалансированные деревья, обеспечивающие эффективное хранение информации на дисках и других устройствах с прямым.
Транксрипт:

Двоичные деревья поиска. Очередь с приоритетами Федор Царев Спецкурс «Олимпиадное программирование» Лекция , Санкт-Петербург, Гимназия 261

Цель лекции Изучить теоретические основы двоичных деревьев поиска и очереди с приоритетами и алгоритмы их обработки Изучить методы реализации этих структур данных и алгоритмов на языке программирования Pascal (Delphi)

Постановка задачи Реализовать структуру данных, хранящую набор чисел и поддерживающую операции: добавить число найти число удалить число найти минимум найти максимум найти k-ое по порядку числу (k-ую порядковую статистику)

Двоичное дерево Дерево, каждая вершина которого имеет не более двух детей На детях каждой вершины задан порядок – есть «левый» ребенок и «правый» ребенок Самая верхняя вершина – корень – не имеет родителя Глубина вершины – расстояние от нее до корня Высота дерева – наибольшая глубина его вершины

Двоичное дерево поиска Это двоичное дерево, в каждой вершине которого хранится число При этом если в некоторой вершине A хранится число x, то: все числа в левом поддереве A меньше чем x все числа в правом поддереве A больше чем x

Дерево поиска неоднозначно Набор чисел: 1, 3, 10, 23, 50 Высота есть O(logn)Высота есть O(n)

Вершина дерева node = record data : integer; left, right : integer; // при реализации // на собственном // менеджере памяти end; -1 соответствует тому, что соответствующего ребенка у вершины нет

Поиск элемента в дереве Если значение y в текущей вершине равно искомому x, то поиск завершен Если x > y, то перейти к правому ребенку Если x < y, то перейти к левому ребенку

Программа function find(x : integer) : boolean; begin cur := root; // root – корень дерева result := false; while (cur -1) do begin if (memory[cur].data = x) then begin result := true; exit; end; if (x > memory[cur].data) then begin cur := memory[cur].right; end else begin cur := memory[cur].left; end;

Поиск минимума и максимума Минимум – самый левый элемент в дереве Максимум – самый правый элемент в дереве

Добавить число Необходимо: 1. Найти место, в котором должно находиться число 2. Создать новый узел дерева и поместить в него это число Считаем, что все числа в дереве различны

Программа (1) function add(root, x : integer) : integer; begin if (root = -1) then begin cur := free; inc(free); memory[cur] := data; result := cur; exit; end; if (memory[root].data = x) then begin // Элемент уже есть в дереве result := root; exit; end;

Программа (2) if (x < memory[root].data) then begin cur := add(memory[root].left, x); memory[root].left := cur; result := root; exit; end; if (x > memory[root].data) then begin cur := add(memory[root].right, x); memory[root].right := cur; result := root; exit; end;

Вызов процедуры root := add(root, x); Здесь root – это корень дерева.

Удаление элемента Необходимо найти элемент Три случая: 1. вершина является листом – просто удаляем 2. у вершины один ребенок – заменяем на ребенка 3. у вершины два ребенка

Третий случай Необходимо найти минимальную вершину в правом поддереве и переместить ее на место удаляемой Проблем с перемещением не возникнет, так как у перемещаемой вершины не более одного ребенка

Время работы операций Время работы всех рассмотренных операций пропорционально высоте дерева – в худшем случае есть O(n) Существуют методы выполнения этих операций так, чтобы высота все время была O(logn): АВЛ-деревья красно-черные деревья … Они будут рассмотрены в следующих лекциях

Упражнение Предложить алгоритм нахождения следующего и предыдущего элемента в двоичном дереве поиска со временем работы пропорциональным высоте дерева

Поиск k-ой порядковой статистики В каждом узле дерева необходимо хранить дополнительную информацию – число узлов в его поддереве node = record data : integer; left, right : integer; size : integer; end; memory[a].size = memory[memory[a].left].size + memory[memory[a].right].size + 1

Поиск k-ого элемента Дано: Корень дерева Число k Если в левом поддереве не меньше, чем k элементов, то переходим к нему Если в левом поддереве ровно k-1 элемент, то k-ый элемент находится в корне Иначе переходим к правому поддереву

Программа function getKth(root, k : integer) : integer; begin sizeLeft := 0; if (memory[root].left -1) then begin sizeLeft := memory[memory[root].left].size; end; if (k

Упражнение Модифицировать операции добавления и удаления вершины, так чтобы они обновляли значения поля «размер поддерева». Время работы операций не должно измениться.

Деревья выражений (5+2)*3 – (1 + 2/3)

Обходы двоичных деревьев Основные варианты обхода двоичного дерева: корень – левое поддерево – правое поддерево левое поддерево – корень – правое поддерево левое поддерево – правое поддерево – корень Им соответствуют: префиксная запись инфиксная запись постфиксная запись

Примеры - * / * 3 – / * / + -

Упражнения Предложить алгоритм вычисления выражений, заданных в постфиксной записи (указание: используйте стек) Применение какого из обходов позволяет вывести элементы дерева поиска в отсортированном порядке?

Очередь с приоритетами Структура данных с двумя операциями: добавить элемент и назначить ему приоритет извлечь элемент с наименьшим приоритетом Как с помощью такой структуры данных реализовать стек? Обычную очередь?

Простая реализация Храним массив записей element = record data, priority : integer; end; Добавление – в конец массива (O(1)) Извлечение – просматриваем весь массив и ищем минимум (O(n))

Структура данных «куча» Полное двоичное дерево Хранится в массиве: Левый ребенок – 2 * i Правый ребенок – 2 * i + 1 Родитель – i div 2 Основное свойство: heap[i] > heap[i div 2] Высота есть O(logn) Можно рассматривать кучу для максимума, а для минимума Иногда эту структуру данных называют «пирамида»

Пример

Добавление элемента (1) Добавим в конец массива После этого основное свойство кучи может быть нарушено

Добавление элемента (2) Необходимо восстановить нарушенное основное свойство Для этого выполним просеивание вверх – будем поднимать элемент вверх до тех пор, пока свойство не будет выполнено

Добавление элемента (3) Число обменов не превышает высоту дерева – то есть O(logn)

Добавление элемента (4) procedure add(x : integer); begin inc(size); heap[size] := x; i := size; while (i > 1) and do begin if (heap[i div 2] > heap[i]) then begin swap(heap[i], heap[i div 2]); end else begin break; end;

Извлечение элемента (1) Минимальный элемент находится на вершине кучи Поменяем его местами с последним и удалим После этого может нарушиться основное свойство

Извлечение элемента (2) Был о Стало Необходимо поместить верхний элемент на его место!

Извлечение элемента (3)

Извлечение элемента (4)

Извлечение элемента (5)

function remove() : integer; begin result := heap[1]; heap[1] := heap[size]; dec(size); i := 1; while (2 * i

Сортировка с помощью кучи Можно добавить все элементы массива в кучу, а потом по очереди извлечь Требуется дополнительный массив – на хранение кучи Чтобы сделать без дополнительной памяти надо: Научиться преобразовывать массив в кучу Научиться преобразовывать кучу в упорядоченный массив

Построение кучи из массива for i := n div 2 downto 1 do begin siftDown(i); end; procedure siftDown(i : integer); begin while (2 * i

Время работы Грубая оценка – O(nlogn) Более точная оценка – O(n)

Построение упорядоченного массива из кучи for j := 1 to n do begin swap(heap[1], heap[size]); dec(size); i := 1; while (2 * i

Время работы heapSort Общее время работы heapSort есть O(n + nlogn) = O(nlogn)

Выводы Двоичные деревья поиска позволяют быстро выполнять словарные операции при условии, что у них небольшая высота С помощью двоичных деревьев можно представлять математические выражения Очередь с приоритетами реализуется на основе структуры данных «куча»

Спасибо за внимание! Вопросы? Комментарии?