Лекция 5: Словари. Бинарные деревья поиска
TRANSCRIPT
![Page 1: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/1.jpg)
Лекция 5: Словари.
Двоичные деревья поиска
Курносов Михаил Георгиевич
к.т.н. доцент Кафедры вычислительных систем
Сибирский государственный университет
телекоммуникаций и информатики
http://www.mkurnosov.net
![Page 2: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/2.jpg)
Контроль
2
1. Описать АТД “двухсторонняя очередь” (дек, deque).
2. Что такое Θ, Ω, O?
![Page 3: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/3.jpg)
Словарь (Map)
3
Словарь (ассоциативный массив, associative array,
map, dictionary) – структура данных для хранения
пар вида “ключ (key) – значение (value)”.
• В словаре не могут храниться пары с одинаковыми
ключами
Ключ (Key) Значение (Value)
Слон 890
Кит 1200
Лев 260
Жираф 530
![Page 4: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/4.jpg)
АТД “Словарь” (Map)
4
Операция Описание
Add(map, key, value)Помещает в словарь map пару
(key, value)
Lookup(map, key)Возвращает из словаря map значение
ассоциированное с ключом key
Remove(map, key) Удаляет из словаря map значение
ассоциированное с ключом key
Min(map)Возвращает из словаря map
минимальное значение
Max(map)Возвращает из словаря map
максимальное значение
![Page 5: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/5.jpg)
Реализация АТД “Словарь” (Map)
5
Существующие реализации словарей, отличаются
вычислительной сложностью операций добавления, поиска
и удаления пар
Наибольшее распространение получили следующие
реализации:
1. Деревья поиска (Search trees)
2. Хэш-таблицы (Hash tables)
3. Связные списки
4. Массивы
![Page 6: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/6.jpg)
Реализация словаря на основе массива
6
ОперацияНеотсортированный
массив
Отсортированный
массив
Add
(map, key, value)
O(1)
(добавление в конец)
O(n)
(поиск позиции)
Lookup
(map, key)O(n)
O(logn)
(бинарный поиск)
Remove
(map, key)
O(n)
(поиск элемента и
перенос последнего на
место удаляемого)
O(n)
(перенос элементов)
Min(map) O(n)O(1)
(элемент v[1])
Max(map) O(n)O(1)
(элемент v[n])
![Page 7: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/7.jpg)
Реализация словаря на основе связного списка
7
ОперацияНеотсортированный
связный список
Отсортированный
связный список
Add
(map, key, value)
O(1)
(добавление в начало)
O(n)
(поиск позиции)
Lookup
(map, key)O(n) O(n)
Remove
(map, key)
O(n)
(поиск элемента)
O(n)
(перенос элементов)
Min(map) O(n) O(1)
Max(map) O(n)
O(n)
или O(1), если
поддерживать
указатель на
последний элемент
![Page 8: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/8.jpg)
Двоичные деревья поиска (Binary Search Trees)
8
Двоичное дерево поиска (Binary Search Tree, BST) –
это двоичное дерево, в котором:
1) каждый узел x (node) имеет не более двух дочерних
узлов (child nodes) и содержит ключ (key) и значение
(value)
2) ключи всех узлов левого поддерева
узла x меньше значения его ключа
3) ключи всех узлов правого поддерева
узла x больше значения его ключа
Key: 530
Value: Жираф
Left Right
![Page 9: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/9.jpg)
Двоичные деревья поиска (Binary Search Trees)
9
Key: 530
Value: Жираф
Left Right
Ключ
(Key)
Значение
(Value)
Слон 890
Кит 1200
Лев 260
Жираф 530
Key: 260
Value: Лев
Left Right
Key: 890
Value: Слон
Left Right
Key: 1200
Value: Кит
Left Right
Словарь Двоичное дерево поиска
![Page 10: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/10.jpg)
Двоичные деревья (Binary trees)
10
Двоичное дерево (Binary tree) – это дерево (структура
данных), в которой каждый узел (node) имеет не более двух
дочерних узлов (child nodes).
Root node
Leaf node
Child nodeParent node
Depth 0
Depth 1
Depth 2
Depth 3
![Page 11: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/11.jpg)
Двоичные деревья поиска (Binary Search Trees)
11
60Волк
35Рысь
90Ягуар
8Лиса
15Барсук
180Тигр
200Лев
4000Слон
600Медведь
Бинарное дерево поиска: 9 элементов, глубина (depth) = 3
![Page 12: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/12.jpg)
Двоичные деревья поиска (Binary Search Trees)
12
#include <stdio.h>
#include <stdlib.h>
struct bstree
int key; /* Ключ */
char *value; /* Данные */
struct bstree *left;
struct bstree *right;
;
![Page 13: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/13.jpg)
Создание элемента BST
13
struct bstree *bstree_create(int key,
char *value)
struct bstree *node;
node = malloc(sizeof(*node));
if (node != NULL)
node->key = key;
node->value = value;
node->left = NULL;
node->right = NULL;
return node;
T = O(1)
![Page 14: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/14.jpg)
Создание элемента BST
14
int main()
struct bstree *tree;
tree = bstree_create(180, "Tigr");
return 0;
![Page 15: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/15.jpg)
Добавление элемента в BST
15
60Волк
15Барсук
180Тигр
200Лев
1. Добавление элемента (180, Тигр)
2. Добавление элемента (200, Лев)
3. Добавление элемента (15, Барсук)
4. Добавление элемента (60, Волк)
Ищем листовой узел (leaf node) для вставки
нового элемента
![Page 16: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/16.jpg)
Добавление элемента в BST
void bstree_add(struct bstree *tree,
int key, char *value)
struct bstree *parent, *node;
if (tree == NULL)
return;
/* Отыскиваем листовой узел */
for (parent = tree; tree != NULL; )
parent = tree;
if (key < tree->key)
tree = tree->left;
else if (key > tree->key)
tree = tree->right;
else
return;
16
![Page 17: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/17.jpg)
Добавление элемента в BST (продолжение)
17
/* Создаем элемент и связываем с узлом */
node = bstree_create(key, value);
if (key < parent->key)
parent->left = node;
else
parent->right = node;
![Page 18: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/18.jpg)
Поиск элемента в BST
18
60Волк
15Барсук
180Тигр
200Лев
1. Сравниваем ключ корневого
узла с искомым. Если совпали,
то элемент найден.
2. Переходим к левому или
правому дочернему узлу и
повторяем шаг 1.
Возможны рекурсивная и не
рекурсивная реализации
![Page 19: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/19.jpg)
Поиск элемента в BST
19
struct bstree *bstree_lookup(struct bstree *tree,
int key)
while (tree != NULL)
if (key == tree->key)
return tree;
else if (key < tree->key)
tree = tree->left;
else
tree = tree->right;
return tree;
![Page 20: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/20.jpg)
Поиск минимального элемента в BST
20
60Волк
15Барсук
180Тигр
200Лев
Минимальный элемент всегда
расположен в левом поддереве
корневого узла.
Требуется найти самого левого
потомка корневого узла.
![Page 21: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/21.jpg)
Поиск минимального элемента в BST
21
struct bstree *bstree_min(struct bstree *tree)
if (tree == NULL)
return NULL;
while (tree->left != NULL)
tree = tree->left;
return tree;
![Page 22: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/22.jpg)
Поиск максимального элемента в BST
22
60Волк
15Барсук
180Тигр
200Лев
Максимальный элемент всегда
расположен в правом поддереве
корневого узла.
Требуется найти самого правого
потомка корневого узла.
![Page 23: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/23.jpg)
Поиск максимального элемента в BST
23
struct bstree *bstree_max(struct bstree *tree)
if (tree == NULL)
return NULL;
while (tree->right != NULL)
tree = tree->right;
return tree;
![Page 24: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/24.jpg)
Пример
24
int main()
struct bstree *tree, *node;
tree = bstree_create(180, "Tigr");
bstree_add(tree, 200, "Lev");
bstree_add(tree, 60, "Volk");
node = bstree_lookup(tree, 200);
printf(“Value = %s\n", node->value);
node = bstree_min(tree);
printf("Min: value = %s\n", node->value);
return 0;
![Page 25: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/25.jpg)
Удаление элемента из BST
25
10Заяц
15Барсук
180Тигр
200Лев
1. Находим узел z с заданным
ключом – O(n)
2. Возможны 3 ситуации:
o узел z не имеет дочерних узлов
o узел z имеет 1 дочерний узел
o узел z имеет 2 дочерних узла 60Волк
90Кабан
![Page 26: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/26.jpg)
Удаление элемента из BST
26
10Заяц
15Барсук
180Тигр
200Лев
Удаление узла “Лев” (случай 1)
1. Находим и удаляем узел “Лев”
из памяти (free)
2. Родительский указатель
(left или right) устанавливаем
в зачение NULL
“Тигр”->right = NULL60Волк
90Кабан
![Page 27: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/27.jpg)
Удаление элемента из BST
27
10Заяц
15Барсук
180Тигр
200Лев
Удаление узла “Волк” (случай 2)
1. Находим узел “Волк”
2. Родительский указатель
узла “Волк” (left или right)
устанавливаем на его дочерний
элемент
3. Удаляем узле “Волк” из памяти60Волк
90Кабан
“Барсук”->right = “Волк”->right
![Page 28: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/28.jpg)
Удаление элемента из BST
28
10Заяц
15Барсук
180Тигр
200Лев
Удаление узла “Барсук” (случай 3)
1. Находим узел “Барсук”
2. Находим узел с минимальным
ключом в правом поддереве
узла “Барсук” – самый
левый лист в поддереве
(узел “Рысь”)
3. Заменяем узел “Барсук”
узлом “Рысь”
60Волк
90Кабан
70Тапир
150Марал
45Рысь
55Кабарга
![Page 29: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/29.jpg)
Удаление элемента из BST
29
10Заяц
15Барсук
180Тигр
200Лев
Удаление узла “Барсук” (случай 3)
60Волк
90Кабан
70Тапир
150Марал
45Рысь
55Кабарга
10Заяц
180Тигр
200Лев
60Волк
90Кабан
70Тапир
150Марал
45Рысь
55Кабарга
![Page 30: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/30.jpg)
Анализ эффективность BST
30
1
Value
2
Value
1. Операции имеют трудоемкость
пропорциональную высоте h дерева.
2. В худшем случае высота дерева O(n)
(вставка элементов в отсортированной
последовательности)
3. В среднем случае высота дерева O(logn) 3
Value
4
Value
NULL
NULL
NULL
bstree_add(tree, “Item”, 1);
bstree_add(tree, “Item”, 2);
bstree_add(tree, “Item”, 3);
bstree_add(tree, “Item”, 4);
Дерево вырождается
в связный список
![Page 31: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/31.jpg)
Реализация словаря на основе BST
31
ОперацияСредний случай
(average case)
Худший случай
(worst case)
Add
(map, key, value)O(logn) O(n)
Lookup
(map, key)O(logn) O(n)
Remove
(map, key) O(logn) O(n)
Min(map) O(logn) O(n)
Max(map) O(logn) O(n)
![Page 32: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/32.jpg)
Сбалансированные деревья поиска
32
Сбалансированное по высоте дерево поиска (self-balancing
binary search tree) – дерево поиска, в котором высоты
поддеревьев различаются не более чем на заданную константу k.
Баланс высоты поддерживается при выполнении операций
добавления и удаления элементов.
Типы сбалансированных деревьев поиска:
o Красно-черные деревья (Red-black tree): ℎ ≤ 2 log( + 1)
o АВЛ-деревья (AVL-tree): ℎ ≤ 1.44 ∙ log ;
o 2-3-деревья (2-3-tree): ℎ ≤ log
o Дерево Ван Эмде Боаса
Все операции на красно-черном дереве в худшем случае
выполняются за время O(logn)
![Page 33: Лекция 5: Словари. Бинарные деревья поиска](https://reader033.vdocuments.net/reader033/viewer/2022042816/559b8b161a28ab67158b4769/html5/thumbnails/33.jpg)
Задание
33
Найти информацию о видах сбалансированных деревьев
поиска (self-balancing search trees)