SlideShare a Scribd company logo
1 of 63
Download to read offline
Лекция 6
Фибоначчиевы кучи
(Fibonacci heap)
Курносов Михаил Георгиевич
E-mail: mkurnosov@gmail.com
WWW: www.mkurnosov.net
Курс «Структуры и алгоритмы обработки данных»
Сибирский государственный университет телекоммуникаций и информатики (Новосибирск)
Осенний семестр, 2015
Значение (Value) Приоритет (Priority)
Слон 3
Кит 1
Лев 15
Очередь с приоритетом (priority queue)
2
 Очередь с приоритетом (priority queue) –
это очередь, в которой элементы имеют приоритет (вес)
 Поддерживаемые операции:
o Insert(key, value) – добавляет в очередь значение value
c приоритетом (весом, ключом) key
o DeleteMin/DeleteMax – удаляет из очереди элемент
с мин./макс. приоритетом (ключом)
o Min/Max – возвращает элемент с мин./макс. ключом
o DecreaseKey – изменяет значение ключа заданного элемента
o Merge(q1, q2) – сливает две очереди в одну
Бинарная куча (binary heap)
3
 Бинарная куча (пирамида, сортирующее дерево,
binary heap) – это бинарное дерево, удовлетворяющее
следующим условиям:
a) приоритет (ключ) любой вершины не меньше ( ≥ ),
приоритета её потомков
b) дерево является завершенным бинарным деревом
(complete binary tree) – все уровни заполнены слева
направо, возможно за исключением последнего
Бинарная куча (binary heap)
4
max-heap
Приоритет любой вершины
не меньше (≥),
приоритета потомков
min-heap
Приоритет любой вершины
не больше (≤),
приоритета потомков
Очередь с приоритетом (priority queue)
5
 В таблице приведены трудоемкости операций очереди
с приоритетом (в худшем случае, worst case)
 Символом ‘*’ отмечена амортизированная сложность операций
Операция
Binary
heap
Binomial
heap
Fibonacci
heap
Pairing
heap
Brodal
heap
FindMin Θ(1) O(logn) Θ(1)* Θ(1)* Θ(1)
DeleteMin Θ(logn) Θ(logn) O(logn)* O(logn)* O(logn)
Insert Θ(logn) O(logn) Θ(1)* Θ(1)* Θ(1)
DecreaseKey Θ(logn) Θ(logn) Θ(1)* O(logn)* Θ(1)
Merge/Union Θ(n) Ω(logn) Θ(1) Θ(1)* Θ(1)
Фибоначчиевы кучи (Fibonacci heaps)
6
 Фибоначчиевы кучи (fibonacci heaps) эффективны, когда количество
операций DeleteMin() и Delete(x) относительно мало по сравнению
с количеством других операций (Min, Insert, Merge, DecreaseKey)
 Фибоначчиевы кучи нашли широкое применение в алгоритмах на
графах (поиск минимального остовного дерева, поиск кратчайшего
пути в графе)
 Например, в алгоритме Дейкстры фибоначчиевы кучи (min-heap)
можно использовать для хранения вершин и быстрого уменьшения
текущего кратчайшего пути до них (DecreaseKey)
 Авторы: Michael L. Fredman, Robert E. Tarjan, 1984
 Fredman M.L., Tarjan R.E. Fibonacci heaps and their uses in improved
network optimization algorithms. – Journal of the Association for
Computing Machinery. – 1987, 34 (3). – pp. 596-615
(http://www.cl.cam.ac.uk/~sos22/supervise/dsaa/fib_heaps.pdf)
Фибоначчиевы кучи (Fibonacci heaps)
7
 Фибоначчиева куча (Fibonacci heap) – это совокупность деревьев,
которые удовлетворяют свойствам кучи (min-heap или max-heap)
 Деревья могу иметь различные степени
 Максимальная степень D(n) узла в фибоначчиевой куче из n
элементов:
𝑫(𝒏) ≤ 𝐥𝐨𝐠 𝒏
23
Min
7 3
18
39
52 38
41
17 24
30 26 46
35
min-heap (5 деревьев, 14 узлов)
 key – приоритет узла (вес, ключ)
 value – данные
 parent – указатель на родительский узел
 child – указатель на один из дочерних узлов
 left – указатель на левый сестринский узел
 right – указатель на правый сестринский узел
 degree – количество дочерних узлов
 mark – были ли потери узлом дочерних узлов
Узел фибоначчиевой кучи
8
 Дочерние узлы (включая корни) объединены в циклический дважды
связный список (doubly linked list)
 Каждый узел фибоначчиевой кучи (дерева) содержит следующие поля:
parent
key
value
mark
degree
left right
child
Узел фибоначчиевой кучи
9
 Если узел является единственным дочерним узлом
x.left = x.right = x
parent
key
value
mark
degree
left right
child
Фибоначчиевы кучи (Fibonacci heaps)
10
 Доступ к фибоначчиевой куче осуществляется по указателю
на корень дерева с минимальным ключом
(или с максимальным ключом, в случае max-heap)
23
Min
7 3
18
39
52 38
41
17 24
30 26 46
35
min-heap (5 деревьев, 14 узлов)
Добавление узла в кучу (Insert)
11
23 7
18
39
52 38
41
17 24
30 26 46
35
3
23 7
18
39
52 38
41
17 24
30 26 46
35
321
Добавление узла с ключом 21
Создаем в памяти новый узел (21) и помещаем его слева от узла
с минимальным ключом (3)
Добавление узла в кучу (Insert)
12
function FibHeapInsert(heap, key, value)
node = AllocateMemory();
node.key = key
node.value = value
node.degree = 0
node.mark = false
node.parent = NULL
node.child = NULL
node.left = node
node.right = node
/* Добавляем node в список корней heap */
FibHeapAddNodeToRootList(node, heap.min)
if heap.min = NULL OR node.key < heap.min.key then
heap.min = node
heap.nnodes = heap.nnodes + 1
return heap
end function TInsert = O(1)
Добавление узла в список корней
13
 Необходимо поместить новый узел node в список корней кучи h
3
 Случай 1: список корней содержит одно дерево
Добавляем новый узел слева от корня дерева и корректируем
циклические связи
h.left = h = h.right
321
Insert(21)
h.left = node
h.right = node
node.right = h
node.left = h
7
Добавление узла в список корней
14
 Необходимо поместить новый узел node в список корней кучи h
 Случай 2: список корней содержит больше одного дерева
Добавляем новый узел слева от корня дерева и корректируем
циклические связи
h.left ≠ h ≠ h.right
321
Insert(21)
lnode = h.left
h.left = node
node.right = h
node.left = lnode
lnode.right = node
3
3 7
или 7
Добавление узла в список корней
15
function FibHeapAddNodeToRootList(node, h)
if h = NULL then
return
if h.left = h then
/* Случай 1: список h содержит 1 корень */
h.left = node
h.right = node
node.right = h
node.left = h
else
/* Случай 2: список h содержит > 1 корня */
lnode = h.left
h.left = node
node.right = h
node.left = lnode
lnode.right = node
end if
end function TAddNodeToRootList = O(1)
Поиск минимального узла (Min)
16
 В фибоначчиевой куче поддерживается указатель на корень дерева
с минимальным ключом
 Поиск минимального узла выполняется за время O(1)
23
Min
7 3
18
39
52 38
41
17 24
30 26 46
35
min-heap (5 деревьев, 14 узлов)
Поиск минимального узла (Min)
17
function FibHeapMin(heap)
return heap.min
end function TMin = O(1)
Слияние фибоначчиевых куч (Union)
18
23 7
18
39
52 38
41
24
30 26 46
35
3
23 7
18
39
52 38
41
17 24
30 26 46
35
3
17
Heap 1 Heap 2
Слияние двух куч
Объединяем списки корней,
корректируем указатель на
минимальный узел
4
4
Слияние фибоначчиевых куч (Union)
19
function FibHeapUnion(heap1, heap2)
heap = AllocateMemory()
heap.min = heap1.min
FibHeapLinkLists(heap1.min, heap2.min)
if (heap1.min = NULL) OR
(heap2.min != NULL AND heap2.min.key < heap1.min.key)
then
heap.min = heap2.min
end if
heap.nnodes = heap1.nnodes + heap2.nnodes
FreeMemory(heap1)
FreeMemory(heap2)
return heap
end function TUnion = O(1)
 Имеется два списка корней – два двусвязных циклических списка
 Каждый список задан указателем на одну из вершин (корень дерева)
 Требуется слить два списка в один
Слияние пары списков корней
20
5
3
7
17 31
1924
Heap 1 Heap 2
 Имеется два списка корней – два двусвязных циклических списка
 Каждый список задан указателем на одну из вершин (корень дерева)
 Требуется слить два списка в один
Слияние пары списков корней
21
5
3
7
17 31
1924
Heap 1 Heap 2
 Требуется корректировка 4 указателей
 Объединение списков выполняется за время O(1)
function FibHeapLinkLists(heap1, heap2)
if heap1 = NULL OR heap2 = NULL then
return
left1 = heap1.left
left2 = heap2.left
left1.right = heap2
heap2.left = left1
heap1.left = left2
left2.right = heap1
return heap1
end function
Слияние пары списков корней
22
TLinkLists = O(1)
Удаление минимального узла (DeleteMin)
23
 Получаем указатель на минимальный узел z
 Удаляем из списка корней узел z
 Перемещаем в список корней все дочерние узлы элемента z
 Уплотняем список корней (Consolidate) – связываем корни
деревьев одинаковой степени, пока в списке корней останется
не больше одного дерева (корня) каждой степени
23 7
18
39
52 38
41
17 24
30 26 46
35
321
Min
Удаление минимального узла (DeleteMin)
24
23 7
18
39
52 38
41
17 24
30 26 46
35
321
23 7 18
39
52 38
41
17 24
30 26 46
35
21
Удаление минимального элемента
Поднимаем в список корней дочерние элементы
минимального узла (3)
function FibHeapDeleteMin(heap)
z = heap.min
if z = NULL then
return NULL
for each x in z.child do
/* Добавляем дочерний узел x в список корней */
FibHeapAddNodeToRootList(x, heap)
x.parent = NULL
end for
/* Удаляем z из списка корней */
FibHeapRemoveNodeFromRootList(z, heap)
if z = z.right then
heap.min = NULL
else
heap.min = z.right
FibHeapConsolidate(heap)
end if
heap.nnodes = heap.nnodes – 1
return z
end function
Слияние пары списков корней
25
O(logn)
Уплотнение списка корней (Consolidate)
26
 Уплотнение списка корней выполняется до тех пора,
пока все корни не будут иметь различные значения поля
degree
1. Находим в списке корней два корня xи yс одинаковой
степенью (x.degree = y.degree) такие, что x.key ≤ y.key
2. Делаем yдочерним узлом x(и наоборот в случае
max-heap); поле x.degreeувеличивается, а пометка
y.markснимается (если была установлена)
 Процедура Consolidate использует вспомогательный
массив указателей A[0, 1, …, D(n)], 𝐷(𝑛) ≤ log 𝑛
 Если A[i] = y, то корень yимеет степень i
function FibHeapConsolidate(heap)
for i = 0 to D(heap.nnodes) do
A[i] = NULL
/* Цикл по всем узлам списка корней */
for each w in heap.min do
x = w
d = x.degree
while A[d] != NULL do
y = A[d] /* Степень y совпадает со степенью x */
if x.key > y.key then
FibHeapSwap(x, y) /* Обмениваем x и y */
FibHeapLink(heap, y, x)
A[d] = NULL
d = d + 1
end while
A[d] = x
end for
Уплотнение списка корней (Consolidate)
27
O(logn)
/* Находим минимальный узел */
heap.min = NULL
for i = 0 to D(heap.nnodes) do
if A[i] != NULL then
/* Добавляем A[i] в список корней */
FibHeapAddNodeToRootList(A[i], heap)
if heap.min = NULL OR A[i].key < heap.min.key then
heap.min = A[i]
end if
end if
end for
end function
Уплотнение списка корней (Consolidate)
28
function D(n)
return floor(log(2, n))
end function
function FibHeapLink(heap, y, x)
x.degree = x.degree + 1
/* Делаем y дочерним узлом x */
FibHeapRemoveNodeFromRootList(y, heap)
y.parent = x
FibHeapAddNodeToRootList(y, x.child)
y.mark = FALSE
end function
Уплотнение списка корней (Consolidate)
29
TLink = O(1)
Уплотнение списка корней (Consolidate)
30
23 7 18
39
52 38
41
17 24
30 26 46
35
21
 В список корней подняли дочерние элементы минимального узла (3),
минимальный узел из списка удалили (cм. DeleteMin)
 Текущим минимальным узлом стал узел (17) – правый сосед узла (3):
heap.min = z.right (причем, z.right возможно не минимальный узел)
Уплотнение списка корней (Consolidate)
31
23 7 18
39
52 38
41
24
30 26 46
35
21
A:
0 1 2 3
- - - -
 В куче n= 15 узлов
 Максимальная степень корня дерева 𝐷 𝑛 ≤ log 𝑛 = 3
 Массив A[0, 1, …, D(n)] = A[0, …, 3]
 A[i] = NULL
17
Уплотнение списка корней (Consolidate)
32
23 7 18
39
52 38
41
24
30 26 46
35
21
A:
0 1 2 3
- - -
 Обход списка корней начинаем c узла heap.min (узел 17)
 Степень узла 17 равна 1, ищем корни степени 1
 A[1] = NULL: в списке нет других корней степени 1
x
17
Уплотнение списка корней (Consolidate)
33
23 7 18
39
52 38
41
24
30 26 46
35
21
A:
0 1 2 3
- -
 Переходим к следующему элементу – узлу 24
 Степень узла 24 равна 2, ищем корни степени 2
 A[2] = NULL: в списке нет других корней степени 2
x
17
Уплотнение списка корней (Consolidate)
34
23 7 18
39
52 38
41
24
30 26 46
35
21
A:
0 1 2 3
-
 Переходим к следующему элементу – узлу 23
 Степень узла 23 равна 0, ищем корни степени 0
 A[0] = NULL: в списке нет других корней степени 0
x
17
Уплотнение списка корней (Consolidate)
35
23
7 18
39
52 38
41
24
30 26 46
35
21
A:
0 1 2 3
- -
 Переходим к следующему элементу – узлу 7
 Степень узла 7 равна 0, ищем корни степени 0
 A[0] = (23): узел 23 имеет также степень 0
 7 < 23: делаем 23 дочерним узлом элемента 7
x
17
Уплотнение списка корней (Consolidate)
36
23
7 18
39
52 38
41
24
30
26 46
35
21
A:
0 1 2 3
- - -
 Степень узла 7 увеличена до 1, ищем корни степени 1
 A[1] = (17): узел 17 имеет также степень 1
 7 < 17: делаем 17 дочерним узлом элемента 7
x
17
Уплотнение списка корней (Consolidate)
37
23
7 18
39
52 38
4124
3026 46
35
21
A:
0 1 2 3
- - - -
 Степень узла 7 увеличена до 2, ищем корни степени 2
 A[2] = (24): узел 24 имеет также степень 2
 7 < 24: делаем 24 дочерним узлом элемента 7
x
17
Уплотнение списка корней (Consolidate)
38
23
7 18
39
52 38
4124
3026 46
35
21
A:
0 1 2 3
- - -
 Степень узла 7 увеличена до 3, ищем корни степени 3
 A[3] = NULL
 Устанавливаем указатель A[3] на узел 7
x
17
Уплотнение списка корней (Consolidate)
39
 Переходим к следующему элементу – узлу 21
 Степень узла 21 равна 0, ищем корни степени 0
 A[0] = NULL, устанавливаем A[0] = (21)
23
7 18
39
52 38
4124
3026 46
35
21
A:
0 1 2 3
- -
x
17
Уплотнение списка корней (Consolidate)
40
 Переходим к следующему элементу – узлу 18
 Степень узла 18 равна 1, ищем корни степени 1
 A[1] = NULL, устанавливаем A[1] = (18)
23
7 18
39
52 38
4124
3026 46
35
21
A:
0 1 2 3
-
x
17
Уплотнение списка корней (Consolidate)
41
 Переходим к следующему элементу – узлу 52
 Степень узла 52 равна 0, ищем корни степени 0: A[0] = (21)
 52 > 21: обмениваем узлы 21 и 52, делаем 52 дочерним узлом эл-та 21
 A[0] = NULL
23
7 18
39
21 38
4124
3026 46
35
A:
0 1 2 3
- -
x
17 52
Уплотнение списка корней (Consolidate)
42
 Степень узла 21 увеличена до 1, ищем корни степени 1
 A[1] = (18)
 21 > 18: обмениваем узлы 21 и 18, делаем 21 дочерним узлом эл-та 18
 A[1] = NULL
23
7
21
39
18 38
4124
3026 46
35
A:
0 1 2 3
- - -
x
17 52
Уплотнение списка корней (Consolidate)
43
 Степень узла 18 увеличена до 2, ищем корни степени 2
 A[2] = NULL
 Устанавливаем A[2] = (18)
23
7
21
39
18 38
4124
3026 46
35
A:
0 1 2 3
- -
x
17 52
Уплотнение списка корней (Consolidate)
44
 Переходим к следующему элементу – узлу 38
 Степень узла 38 равна 1, ищем корни степени 1: A[1] = NULL
 Устанавливаем A[1] = (38)
23
7
21
39
18 38
4124
3026 46
35
A:
0 1 2 3
-
x
17 52
Уплотнение списка корней (Consolidate)
45
 Обход списка корней завершён
 Все корни имеют различные степени: 3, 2, 1
23
7
21
39
18 38
4124
3026 46
35
A:
0 1 2 3
-
x
17 52
Уплотнение списка корней (Consolidate)
46
23
7
21
39
18 38
4124
3026 46
35
A:
0 1 2 3
-
x
17 52
 Ищем новый минимальный узел (устанавливаем heap.min)
 Проходим по указателям массива A[0, 1, …, D(n)] = A[0, …, 3]
и запоминаем указатель на корень с минимальным ключом
(требуется O(logn) шагов)
Уменьшение ключа (DecreaseKey)
47
23 21
39
18 38
4124
3046
35
17 52
7
 Изменяем ключ заданного узла на новое значение
 Если нарушены свойства кучи (min-heap):
ключ текущего узла меньше ключа родителя,
то осуществляем восстановление свойств кучи
26newkey
Уменьшение ключа (DecreaseKey)
48
function FibHeapDecreaseKey(heap, x, newkey)
if newkey > x.key then
return /* Новый ключ больше текущего значения ключа */
x.key = newkey
y = x.parent
if y != NULL AND x.key < y.key then
/* Нарушены свойства min-heap: ключ родителя больше */
/* Вырезаем x и переносим его в список корней */
FibHeapCut(heap, x, y)
FibHeapCascadingCut(heap, y)
end if
/* Корректируем указатель на минимальный узел */
if x.key < heap.min.key then
heap.min = x
end function
Уменьшение ключа (DecreaseKey)
49
function FibHeapCut(heap, x, y)
/* Удаляем x из списка дочерних узлов y */
FibHeapRemoveNodeFromRootList(x, y)
y.degree = y.degree - 1
/* Добавляем x в список корней кучи heap */
FibHeapAddNodeToRootList(x, heap)
x.parent = NULL
x.mark = FALSE
end function TCut = O(1)
 Функция FibHeapCut вырезает связь между x и его
родительским узлом y, делая x корнем
Уменьшение ключа (DecreaseKey)
50
function FibHeapCascadingCut(heap, y)
z = y.parent
if z = NULL then
return
if y.mark = FALSE then
y.mark = TRUE
else
FibHeapCut(heap, y, z)
FibHeapCascadingCut(heap, z)
end if
end function
 Функция FibHeapCascadingCut реализует каскадное
вырезание над y
Уменьшение ключа (DecreaseKey)
51
23 21
39
18 38
4124
30
35
17 52
7
26
x
 Изменим ключ 46 до значения 15
46
Уменьшение ключа (DecreaseKey)
52
23 21
39
18 38
4124
30
35
17 52
7
26
 Изменим ключ 46 до значения 15
 Устанавливаем в узле 46 новый ключ 15
 Нарушены свойства кучи min-heap: 15 < 24 (x.key < y.key)
 Выполняет FibHeapCut(<15>, <24>)
 Выполняем FibHeapCascadingCut(<24>)
15
x
y
Уменьшение ключа (DecreaseKey)
53
23 21
39
18 38
4124
30
35
17 52
7
26
 Выполняет FibHeapCut(<15>, <24>)
o Переносим <15> в список корней кучи
o Устанавливаем <15>.mark = FALSE
15
x
y
Уменьшение ключа (DecreaseKey)
54
23 21
39
18 38
4124
30
35
17 52
7
26
 Выполняем FibHeapCascadingCut(<24>)
o Изменяем значение <24>.mark с FALSE на TRUE
15
y
z
Уменьшение ключа (DecreaseKey)
55
23 21
39
18 38
4124
30
35
17 52
7
26
 Корректируем указатель на минимальный элемент
 15 > 7, указатель не изменяется
15
x
Уменьшение ключа (DecreaseKey)
56
23 21
39
18 38
4124
30
35
17 52
7
26
15
x
 Изменим ключ 35 до значения 5
Уменьшение ключа (DecreaseKey)
57
23 21
39
18 38
4124
30
5
17 52
7
26
15
x
 Изменим ключ 35 до значения 5
 Устанавливаем в узле 35 новый ключ 5
 Нарушены свойства кучи min-heap: 5 < 25 (x.key < y.key)
 Выполняет FibHeapCut(<5>, <26>)
 Выполняем FibHeapCascadingCut(<26>)
y
Уменьшение ключа (DecreaseKey)
58
23 21
39
18 38
4124
30
5
17 52
7
26
15
x
y
 Выполняет FibHeapCut(<15>, <24>)
o Переносим <15> в список корней кучи
o Устанавливаем <15>.mark = FALSE
Уменьшение ключа (DecreaseKey)
59
23 21
39
18 38
4124
30
5
17 52
7
26
15
z
y
 Выполняем FibHeapCascadingCut(<26>)
o Изменяем значение <26>.mark с FALSE на TRUE
Уменьшение ключа (DecreaseKey)
60
23 21
39
18 38
4124
30
5
17 52
7
26
15
 Корректируем указатель на минимальный элемент
 5 < 7, указатель не изменяется
Удаление заданного узла (Delete)
61
function FibHeapDelete(heap, x)
FibHeapDecreaseKey(heap, x, -Infinity)
FibHeapDeleteMin(heap)
end function
Очередь с приоритетом (Priority queue)
62
 В таблице приведены трудоемкости операций очереди
с приоритетом (в худшем случае, worst case)
 Символом ‘*’ отмечена амортизированная сложность операций
Операция
Binary
heap
Binomial
heap
Fibonacci
heap
Pairing
heap
Brodal
heap
FindMin Θ(1) O(logn) Θ(1)* Θ(1)* Θ(1)
DeleteMin Θ(logn) Θ(logn) O(logn)* O(logn)* O(logn)
Insert Θ(logn) O(logn) Θ(1)* Θ(1)* Θ(1)
DecreaseKey Θ(logn) Θ(logn) Θ(1)* O(logn)* Θ(1)
Merge/Union Θ(n) Ω(logn) Θ(1) Θ(1)* Θ(1)
Задания
63
 Прочитать в CLRS 3ed.
§ “19.2 Операции над объединяемыми пирамидами”
 Разобраться с доказательством амортизированной
вычислительной сложности операций (метод потенциалов)
 Прочитать в CLRS 3ed.
§ “19.4 Оценка максимальной степени”

More Related Content

Viewers also liked

Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовMikhail Kurnosov
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Mikhail Kurnosov
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Mikhail Kurnosov
 
Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)Mikhail Kurnosov
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиMikhail Kurnosov
 
Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Mikhail Kurnosov
 
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Mikhail Kurnosov
 
Векторизация кода (семинар 2)
Векторизация кода (семинар 2)Векторизация кода (семинар 2)
Векторизация кода (семинар 2)Mikhail Kurnosov
 
Лекция 6: Хеш-таблицы
Лекция 6: Хеш-таблицыЛекция 6: Хеш-таблицы
Лекция 6: Хеш-таблицыMikhail Kurnosov
 

Viewers also liked (9)

Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмов
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
 
Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимости
 
Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)Лекция 4. Префиксные деревья (tries, prefix trees)
Лекция 4. Префиксные деревья (tries, prefix trees)
 
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
 
Векторизация кода (семинар 2)
Векторизация кода (семинар 2)Векторизация кода (семинар 2)
Векторизация кода (семинар 2)
 
Лекция 6: Хеш-таблицы
Лекция 6: Хеш-таблицыЛекция 6: Хеш-таблицы
Лекция 6: Хеш-таблицы
 

Similar to Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)

Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Mikhail Kurnosov
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиMikhail Kurnosov
 
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)Mikhail Kurnosov
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаMikhail Kurnosov
 
Лекция 7: Бинарные кучи (пирамиды)
Лекция 7: Бинарные кучи (пирамиды)Лекция 7: Бинарные кучи (пирамиды)
Лекция 7: Бинарные кучи (пирамиды)Mikhail Kurnosov
 
Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)Mikhail Kurnosov
 
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)Mikhail Kurnosov
 
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)Mikhail Kurnosov
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?tfmailru
 
03 двоичные деревья поиска и очередь с приоритетами
03 двоичные деревья поиска и очередь с приоритетами03 двоичные деревья поиска и очередь с приоритетами
03 двоичные деревья поиска и очередь с приоритетамиFedor Tsarev
 
Алгоритмы и структуры данных осень 2013 лекция 2
Алгоритмы и структуры данных осень 2013 лекция 2Алгоритмы и структуры данных осень 2013 лекция 2
Алгоритмы и структуры данных осень 2013 лекция 2Technopark
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиMikhail Kurnosov
 
Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1simple_people
 
Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Sergey Tihon
 
Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)Mikhail Kurnosov
 
Алгоритмы и структуры данных осень 2013 лекция 4
Алгоритмы и структуры данных осень 2013 лекция 4Алгоритмы и структуры данных осень 2013 лекция 4
Алгоритмы и структуры данных осень 2013 лекция 4Technopark
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?tfmailru
 
Лекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмовЛекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмовMikhail Kurnosov
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Fwdays
 

Similar to Лекция 6. Фибоначчиевы кучи (Fibonacci heaps) (20)

Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные списки
 
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
Лекция 9. Дерево ван Эмде Боаса (van Emde Boas tree)
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
 
Лекция 7: Бинарные кучи (пирамиды)
Лекция 7: Бинарные кучи (пирамиды)Лекция 7: Бинарные кучи (пирамиды)
Лекция 7: Бинарные кучи (пирамиды)
 
Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)
 
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
 
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
 
03 двоичные деревья поиска и очередь с приоритетами
03 двоичные деревья поиска и очередь с приоритетами03 двоичные деревья поиска и очередь с приоритетами
03 двоичные деревья поиска и очередь с приоритетами
 
Алгоритмы и структуры данных осень 2013 лекция 2
Алгоритмы и структуры данных осень 2013 лекция 2Алгоритмы и структуры данных осень 2013 лекция 2
Алгоритмы и структуры данных осень 2013 лекция 2
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные списки
 
Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1Лекция 3 Элементарные структуры данных Часть 1
Лекция 3 Элементарные структуры данных Часть 1
 
Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.
 
Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)Лекция 6: Биномиальные кучи (Binomial heaps)
Лекция 6: Биномиальные кучи (Binomial heaps)
 
Основы Python. Функции
Основы Python. ФункцииОсновы Python. Функции
Основы Python. Функции
 
Алгоритмы и структуры данных осень 2013 лекция 4
Алгоритмы и структуры данных осень 2013 лекция 4Алгоритмы и структуры данных осень 2013 лекция 4
Алгоритмы и структуры данных осень 2013 лекция 4
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
 
Лекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмовЛекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмов
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"
 

More from Mikhail Kurnosov

Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Mikhail Kurnosov
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Mikhail Kurnosov
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Mikhail Kurnosov
 
Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Mikhail Kurnosov
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPMikhail Kurnosov
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...Mikhail Kurnosov
 
Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)Mikhail Kurnosov
 
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Mikhail Kurnosov
 
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...Mikhail Kurnosov
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Mikhail Kurnosov
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Mikhail Kurnosov
 
Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)Mikhail Kurnosov
 
Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)Mikhail Kurnosov
 
Лекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графеЛекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графеMikhail Kurnosov
 
Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Mikhail Kurnosov
 
Лекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовMikhail Kurnosov
 
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)Mikhail Kurnosov
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Mikhail Kurnosov
 
Лекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицыЛекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицыMikhail Kurnosov
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Mikhail Kurnosov
 

More from Mikhail Kurnosov (20)

Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Векторизация кода (семинар 3)
Векторизация кода (семинар 3)
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
 
Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
 
Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)Лекция 5. B-деревья (B-trees, k-way merge sort)
Лекция 5. B-деревья (B-trees, k-way merge sort)
 
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
 
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
Лекция 3. Оптимизация доступа к памяти (Memory access optimization, cache opt...
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)
 
Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)
 
Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)
 
Лекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графеЛекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графе
 
Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)
 
Лекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графов
 
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
 
Лекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицыЛекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицы
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 

Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)

  • 1. Лекция 6 Фибоначчиевы кучи (Fibonacci heap) Курносов Михаил Георгиевич E-mail: mkurnosov@gmail.com WWW: www.mkurnosov.net Курс «Структуры и алгоритмы обработки данных» Сибирский государственный университет телекоммуникаций и информатики (Новосибирск) Осенний семестр, 2015
  • 2. Значение (Value) Приоритет (Priority) Слон 3 Кит 1 Лев 15 Очередь с приоритетом (priority queue) 2  Очередь с приоритетом (priority queue) – это очередь, в которой элементы имеют приоритет (вес)  Поддерживаемые операции: o Insert(key, value) – добавляет в очередь значение value c приоритетом (весом, ключом) key o DeleteMin/DeleteMax – удаляет из очереди элемент с мин./макс. приоритетом (ключом) o Min/Max – возвращает элемент с мин./макс. ключом o DecreaseKey – изменяет значение ключа заданного элемента o Merge(q1, q2) – сливает две очереди в одну
  • 3. Бинарная куча (binary heap) 3  Бинарная куча (пирамида, сортирующее дерево, binary heap) – это бинарное дерево, удовлетворяющее следующим условиям: a) приоритет (ключ) любой вершины не меньше ( ≥ ), приоритета её потомков b) дерево является завершенным бинарным деревом (complete binary tree) – все уровни заполнены слева направо, возможно за исключением последнего
  • 4. Бинарная куча (binary heap) 4 max-heap Приоритет любой вершины не меньше (≥), приоритета потомков min-heap Приоритет любой вершины не больше (≤), приоритета потомков
  • 5. Очередь с приоритетом (priority queue) 5  В таблице приведены трудоемкости операций очереди с приоритетом (в худшем случае, worst case)  Символом ‘*’ отмечена амортизированная сложность операций Операция Binary heap Binomial heap Fibonacci heap Pairing heap Brodal heap FindMin Θ(1) O(logn) Θ(1)* Θ(1)* Θ(1) DeleteMin Θ(logn) Θ(logn) O(logn)* O(logn)* O(logn) Insert Θ(logn) O(logn) Θ(1)* Θ(1)* Θ(1) DecreaseKey Θ(logn) Θ(logn) Θ(1)* O(logn)* Θ(1) Merge/Union Θ(n) Ω(logn) Θ(1) Θ(1)* Θ(1)
  • 6. Фибоначчиевы кучи (Fibonacci heaps) 6  Фибоначчиевы кучи (fibonacci heaps) эффективны, когда количество операций DeleteMin() и Delete(x) относительно мало по сравнению с количеством других операций (Min, Insert, Merge, DecreaseKey)  Фибоначчиевы кучи нашли широкое применение в алгоритмах на графах (поиск минимального остовного дерева, поиск кратчайшего пути в графе)  Например, в алгоритме Дейкстры фибоначчиевы кучи (min-heap) можно использовать для хранения вершин и быстрого уменьшения текущего кратчайшего пути до них (DecreaseKey)  Авторы: Michael L. Fredman, Robert E. Tarjan, 1984  Fredman M.L., Tarjan R.E. Fibonacci heaps and their uses in improved network optimization algorithms. – Journal of the Association for Computing Machinery. – 1987, 34 (3). – pp. 596-615 (http://www.cl.cam.ac.uk/~sos22/supervise/dsaa/fib_heaps.pdf)
  • 7. Фибоначчиевы кучи (Fibonacci heaps) 7  Фибоначчиева куча (Fibonacci heap) – это совокупность деревьев, которые удовлетворяют свойствам кучи (min-heap или max-heap)  Деревья могу иметь различные степени  Максимальная степень D(n) узла в фибоначчиевой куче из n элементов: 𝑫(𝒏) ≤ 𝐥𝐨𝐠 𝒏 23 Min 7 3 18 39 52 38 41 17 24 30 26 46 35 min-heap (5 деревьев, 14 узлов)
  • 8.  key – приоритет узла (вес, ключ)  value – данные  parent – указатель на родительский узел  child – указатель на один из дочерних узлов  left – указатель на левый сестринский узел  right – указатель на правый сестринский узел  degree – количество дочерних узлов  mark – были ли потери узлом дочерних узлов Узел фибоначчиевой кучи 8  Дочерние узлы (включая корни) объединены в циклический дважды связный список (doubly linked list)  Каждый узел фибоначчиевой кучи (дерева) содержит следующие поля: parent key value mark degree left right child
  • 9. Узел фибоначчиевой кучи 9  Если узел является единственным дочерним узлом x.left = x.right = x parent key value mark degree left right child
  • 10. Фибоначчиевы кучи (Fibonacci heaps) 10  Доступ к фибоначчиевой куче осуществляется по указателю на корень дерева с минимальным ключом (или с максимальным ключом, в случае max-heap) 23 Min 7 3 18 39 52 38 41 17 24 30 26 46 35 min-heap (5 деревьев, 14 узлов)
  • 11. Добавление узла в кучу (Insert) 11 23 7 18 39 52 38 41 17 24 30 26 46 35 3 23 7 18 39 52 38 41 17 24 30 26 46 35 321 Добавление узла с ключом 21 Создаем в памяти новый узел (21) и помещаем его слева от узла с минимальным ключом (3)
  • 12. Добавление узла в кучу (Insert) 12 function FibHeapInsert(heap, key, value) node = AllocateMemory(); node.key = key node.value = value node.degree = 0 node.mark = false node.parent = NULL node.child = NULL node.left = node node.right = node /* Добавляем node в список корней heap */ FibHeapAddNodeToRootList(node, heap.min) if heap.min = NULL OR node.key < heap.min.key then heap.min = node heap.nnodes = heap.nnodes + 1 return heap end function TInsert = O(1)
  • 13. Добавление узла в список корней 13  Необходимо поместить новый узел node в список корней кучи h 3  Случай 1: список корней содержит одно дерево Добавляем новый узел слева от корня дерева и корректируем циклические связи h.left = h = h.right 321 Insert(21) h.left = node h.right = node node.right = h node.left = h
  • 14. 7 Добавление узла в список корней 14  Необходимо поместить новый узел node в список корней кучи h  Случай 2: список корней содержит больше одного дерева Добавляем новый узел слева от корня дерева и корректируем циклические связи h.left ≠ h ≠ h.right 321 Insert(21) lnode = h.left h.left = node node.right = h node.left = lnode lnode.right = node 3 3 7 или 7
  • 15. Добавление узла в список корней 15 function FibHeapAddNodeToRootList(node, h) if h = NULL then return if h.left = h then /* Случай 1: список h содержит 1 корень */ h.left = node h.right = node node.right = h node.left = h else /* Случай 2: список h содержит > 1 корня */ lnode = h.left h.left = node node.right = h node.left = lnode lnode.right = node end if end function TAddNodeToRootList = O(1)
  • 16. Поиск минимального узла (Min) 16  В фибоначчиевой куче поддерживается указатель на корень дерева с минимальным ключом  Поиск минимального узла выполняется за время O(1) 23 Min 7 3 18 39 52 38 41 17 24 30 26 46 35 min-heap (5 деревьев, 14 узлов)
  • 17. Поиск минимального узла (Min) 17 function FibHeapMin(heap) return heap.min end function TMin = O(1)
  • 18. Слияние фибоначчиевых куч (Union) 18 23 7 18 39 52 38 41 24 30 26 46 35 3 23 7 18 39 52 38 41 17 24 30 26 46 35 3 17 Heap 1 Heap 2 Слияние двух куч Объединяем списки корней, корректируем указатель на минимальный узел 4 4
  • 19. Слияние фибоначчиевых куч (Union) 19 function FibHeapUnion(heap1, heap2) heap = AllocateMemory() heap.min = heap1.min FibHeapLinkLists(heap1.min, heap2.min) if (heap1.min = NULL) OR (heap2.min != NULL AND heap2.min.key < heap1.min.key) then heap.min = heap2.min end if heap.nnodes = heap1.nnodes + heap2.nnodes FreeMemory(heap1) FreeMemory(heap2) return heap end function TUnion = O(1)
  • 20.  Имеется два списка корней – два двусвязных циклических списка  Каждый список задан указателем на одну из вершин (корень дерева)  Требуется слить два списка в один Слияние пары списков корней 20 5 3 7 17 31 1924 Heap 1 Heap 2
  • 21.  Имеется два списка корней – два двусвязных циклических списка  Каждый список задан указателем на одну из вершин (корень дерева)  Требуется слить два списка в один Слияние пары списков корней 21 5 3 7 17 31 1924 Heap 1 Heap 2  Требуется корректировка 4 указателей  Объединение списков выполняется за время O(1)
  • 22. function FibHeapLinkLists(heap1, heap2) if heap1 = NULL OR heap2 = NULL then return left1 = heap1.left left2 = heap2.left left1.right = heap2 heap2.left = left1 heap1.left = left2 left2.right = heap1 return heap1 end function Слияние пары списков корней 22 TLinkLists = O(1)
  • 23. Удаление минимального узла (DeleteMin) 23  Получаем указатель на минимальный узел z  Удаляем из списка корней узел z  Перемещаем в список корней все дочерние узлы элемента z  Уплотняем список корней (Consolidate) – связываем корни деревьев одинаковой степени, пока в списке корней останется не больше одного дерева (корня) каждой степени 23 7 18 39 52 38 41 17 24 30 26 46 35 321 Min
  • 24. Удаление минимального узла (DeleteMin) 24 23 7 18 39 52 38 41 17 24 30 26 46 35 321 23 7 18 39 52 38 41 17 24 30 26 46 35 21 Удаление минимального элемента Поднимаем в список корней дочерние элементы минимального узла (3)
  • 25. function FibHeapDeleteMin(heap) z = heap.min if z = NULL then return NULL for each x in z.child do /* Добавляем дочерний узел x в список корней */ FibHeapAddNodeToRootList(x, heap) x.parent = NULL end for /* Удаляем z из списка корней */ FibHeapRemoveNodeFromRootList(z, heap) if z = z.right then heap.min = NULL else heap.min = z.right FibHeapConsolidate(heap) end if heap.nnodes = heap.nnodes – 1 return z end function Слияние пары списков корней 25 O(logn)
  • 26. Уплотнение списка корней (Consolidate) 26  Уплотнение списка корней выполняется до тех пора, пока все корни не будут иметь различные значения поля degree 1. Находим в списке корней два корня xи yс одинаковой степенью (x.degree = y.degree) такие, что x.key ≤ y.key 2. Делаем yдочерним узлом x(и наоборот в случае max-heap); поле x.degreeувеличивается, а пометка y.markснимается (если была установлена)  Процедура Consolidate использует вспомогательный массив указателей A[0, 1, …, D(n)], 𝐷(𝑛) ≤ log 𝑛  Если A[i] = y, то корень yимеет степень i
  • 27. function FibHeapConsolidate(heap) for i = 0 to D(heap.nnodes) do A[i] = NULL /* Цикл по всем узлам списка корней */ for each w in heap.min do x = w d = x.degree while A[d] != NULL do y = A[d] /* Степень y совпадает со степенью x */ if x.key > y.key then FibHeapSwap(x, y) /* Обмениваем x и y */ FibHeapLink(heap, y, x) A[d] = NULL d = d + 1 end while A[d] = x end for Уплотнение списка корней (Consolidate) 27 O(logn)
  • 28. /* Находим минимальный узел */ heap.min = NULL for i = 0 to D(heap.nnodes) do if A[i] != NULL then /* Добавляем A[i] в список корней */ FibHeapAddNodeToRootList(A[i], heap) if heap.min = NULL OR A[i].key < heap.min.key then heap.min = A[i] end if end if end for end function Уплотнение списка корней (Consolidate) 28 function D(n) return floor(log(2, n)) end function
  • 29. function FibHeapLink(heap, y, x) x.degree = x.degree + 1 /* Делаем y дочерним узлом x */ FibHeapRemoveNodeFromRootList(y, heap) y.parent = x FibHeapAddNodeToRootList(y, x.child) y.mark = FALSE end function Уплотнение списка корней (Consolidate) 29 TLink = O(1)
  • 30. Уплотнение списка корней (Consolidate) 30 23 7 18 39 52 38 41 17 24 30 26 46 35 21  В список корней подняли дочерние элементы минимального узла (3), минимальный узел из списка удалили (cм. DeleteMin)  Текущим минимальным узлом стал узел (17) – правый сосед узла (3): heap.min = z.right (причем, z.right возможно не минимальный узел)
  • 31. Уплотнение списка корней (Consolidate) 31 23 7 18 39 52 38 41 24 30 26 46 35 21 A: 0 1 2 3 - - - -  В куче n= 15 узлов  Максимальная степень корня дерева 𝐷 𝑛 ≤ log 𝑛 = 3  Массив A[0, 1, …, D(n)] = A[0, …, 3]  A[i] = NULL 17
  • 32. Уплотнение списка корней (Consolidate) 32 23 7 18 39 52 38 41 24 30 26 46 35 21 A: 0 1 2 3 - - -  Обход списка корней начинаем c узла heap.min (узел 17)  Степень узла 17 равна 1, ищем корни степени 1  A[1] = NULL: в списке нет других корней степени 1 x 17
  • 33. Уплотнение списка корней (Consolidate) 33 23 7 18 39 52 38 41 24 30 26 46 35 21 A: 0 1 2 3 - -  Переходим к следующему элементу – узлу 24  Степень узла 24 равна 2, ищем корни степени 2  A[2] = NULL: в списке нет других корней степени 2 x 17
  • 34. Уплотнение списка корней (Consolidate) 34 23 7 18 39 52 38 41 24 30 26 46 35 21 A: 0 1 2 3 -  Переходим к следующему элементу – узлу 23  Степень узла 23 равна 0, ищем корни степени 0  A[0] = NULL: в списке нет других корней степени 0 x 17
  • 35. Уплотнение списка корней (Consolidate) 35 23 7 18 39 52 38 41 24 30 26 46 35 21 A: 0 1 2 3 - -  Переходим к следующему элементу – узлу 7  Степень узла 7 равна 0, ищем корни степени 0  A[0] = (23): узел 23 имеет также степень 0  7 < 23: делаем 23 дочерним узлом элемента 7 x 17
  • 36. Уплотнение списка корней (Consolidate) 36 23 7 18 39 52 38 41 24 30 26 46 35 21 A: 0 1 2 3 - - -  Степень узла 7 увеличена до 1, ищем корни степени 1  A[1] = (17): узел 17 имеет также степень 1  7 < 17: делаем 17 дочерним узлом элемента 7 x 17
  • 37. Уплотнение списка корней (Consolidate) 37 23 7 18 39 52 38 4124 3026 46 35 21 A: 0 1 2 3 - - - -  Степень узла 7 увеличена до 2, ищем корни степени 2  A[2] = (24): узел 24 имеет также степень 2  7 < 24: делаем 24 дочерним узлом элемента 7 x 17
  • 38. Уплотнение списка корней (Consolidate) 38 23 7 18 39 52 38 4124 3026 46 35 21 A: 0 1 2 3 - - -  Степень узла 7 увеличена до 3, ищем корни степени 3  A[3] = NULL  Устанавливаем указатель A[3] на узел 7 x 17
  • 39. Уплотнение списка корней (Consolidate) 39  Переходим к следующему элементу – узлу 21  Степень узла 21 равна 0, ищем корни степени 0  A[0] = NULL, устанавливаем A[0] = (21) 23 7 18 39 52 38 4124 3026 46 35 21 A: 0 1 2 3 - - x 17
  • 40. Уплотнение списка корней (Consolidate) 40  Переходим к следующему элементу – узлу 18  Степень узла 18 равна 1, ищем корни степени 1  A[1] = NULL, устанавливаем A[1] = (18) 23 7 18 39 52 38 4124 3026 46 35 21 A: 0 1 2 3 - x 17
  • 41. Уплотнение списка корней (Consolidate) 41  Переходим к следующему элементу – узлу 52  Степень узла 52 равна 0, ищем корни степени 0: A[0] = (21)  52 > 21: обмениваем узлы 21 и 52, делаем 52 дочерним узлом эл-та 21  A[0] = NULL 23 7 18 39 21 38 4124 3026 46 35 A: 0 1 2 3 - - x 17 52
  • 42. Уплотнение списка корней (Consolidate) 42  Степень узла 21 увеличена до 1, ищем корни степени 1  A[1] = (18)  21 > 18: обмениваем узлы 21 и 18, делаем 21 дочерним узлом эл-та 18  A[1] = NULL 23 7 21 39 18 38 4124 3026 46 35 A: 0 1 2 3 - - - x 17 52
  • 43. Уплотнение списка корней (Consolidate) 43  Степень узла 18 увеличена до 2, ищем корни степени 2  A[2] = NULL  Устанавливаем A[2] = (18) 23 7 21 39 18 38 4124 3026 46 35 A: 0 1 2 3 - - x 17 52
  • 44. Уплотнение списка корней (Consolidate) 44  Переходим к следующему элементу – узлу 38  Степень узла 38 равна 1, ищем корни степени 1: A[1] = NULL  Устанавливаем A[1] = (38) 23 7 21 39 18 38 4124 3026 46 35 A: 0 1 2 3 - x 17 52
  • 45. Уплотнение списка корней (Consolidate) 45  Обход списка корней завершён  Все корни имеют различные степени: 3, 2, 1 23 7 21 39 18 38 4124 3026 46 35 A: 0 1 2 3 - x 17 52
  • 46. Уплотнение списка корней (Consolidate) 46 23 7 21 39 18 38 4124 3026 46 35 A: 0 1 2 3 - x 17 52  Ищем новый минимальный узел (устанавливаем heap.min)  Проходим по указателям массива A[0, 1, …, D(n)] = A[0, …, 3] и запоминаем указатель на корень с минимальным ключом (требуется O(logn) шагов)
  • 47. Уменьшение ключа (DecreaseKey) 47 23 21 39 18 38 4124 3046 35 17 52 7  Изменяем ключ заданного узла на новое значение  Если нарушены свойства кучи (min-heap): ключ текущего узла меньше ключа родителя, то осуществляем восстановление свойств кучи 26newkey
  • 48. Уменьшение ключа (DecreaseKey) 48 function FibHeapDecreaseKey(heap, x, newkey) if newkey > x.key then return /* Новый ключ больше текущего значения ключа */ x.key = newkey y = x.parent if y != NULL AND x.key < y.key then /* Нарушены свойства min-heap: ключ родителя больше */ /* Вырезаем x и переносим его в список корней */ FibHeapCut(heap, x, y) FibHeapCascadingCut(heap, y) end if /* Корректируем указатель на минимальный узел */ if x.key < heap.min.key then heap.min = x end function
  • 49. Уменьшение ключа (DecreaseKey) 49 function FibHeapCut(heap, x, y) /* Удаляем x из списка дочерних узлов y */ FibHeapRemoveNodeFromRootList(x, y) y.degree = y.degree - 1 /* Добавляем x в список корней кучи heap */ FibHeapAddNodeToRootList(x, heap) x.parent = NULL x.mark = FALSE end function TCut = O(1)  Функция FibHeapCut вырезает связь между x и его родительским узлом y, делая x корнем
  • 50. Уменьшение ключа (DecreaseKey) 50 function FibHeapCascadingCut(heap, y) z = y.parent if z = NULL then return if y.mark = FALSE then y.mark = TRUE else FibHeapCut(heap, y, z) FibHeapCascadingCut(heap, z) end if end function  Функция FibHeapCascadingCut реализует каскадное вырезание над y
  • 51. Уменьшение ключа (DecreaseKey) 51 23 21 39 18 38 4124 30 35 17 52 7 26 x  Изменим ключ 46 до значения 15 46
  • 52. Уменьшение ключа (DecreaseKey) 52 23 21 39 18 38 4124 30 35 17 52 7 26  Изменим ключ 46 до значения 15  Устанавливаем в узле 46 новый ключ 15  Нарушены свойства кучи min-heap: 15 < 24 (x.key < y.key)  Выполняет FibHeapCut(<15>, <24>)  Выполняем FibHeapCascadingCut(<24>) 15 x y
  • 53. Уменьшение ключа (DecreaseKey) 53 23 21 39 18 38 4124 30 35 17 52 7 26  Выполняет FibHeapCut(<15>, <24>) o Переносим <15> в список корней кучи o Устанавливаем <15>.mark = FALSE 15 x y
  • 54. Уменьшение ключа (DecreaseKey) 54 23 21 39 18 38 4124 30 35 17 52 7 26  Выполняем FibHeapCascadingCut(<24>) o Изменяем значение <24>.mark с FALSE на TRUE 15 y z
  • 55. Уменьшение ключа (DecreaseKey) 55 23 21 39 18 38 4124 30 35 17 52 7 26  Корректируем указатель на минимальный элемент  15 > 7, указатель не изменяется 15 x
  • 56. Уменьшение ключа (DecreaseKey) 56 23 21 39 18 38 4124 30 35 17 52 7 26 15 x  Изменим ключ 35 до значения 5
  • 57. Уменьшение ключа (DecreaseKey) 57 23 21 39 18 38 4124 30 5 17 52 7 26 15 x  Изменим ключ 35 до значения 5  Устанавливаем в узле 35 новый ключ 5  Нарушены свойства кучи min-heap: 5 < 25 (x.key < y.key)  Выполняет FibHeapCut(<5>, <26>)  Выполняем FibHeapCascadingCut(<26>) y
  • 58. Уменьшение ключа (DecreaseKey) 58 23 21 39 18 38 4124 30 5 17 52 7 26 15 x y  Выполняет FibHeapCut(<15>, <24>) o Переносим <15> в список корней кучи o Устанавливаем <15>.mark = FALSE
  • 59. Уменьшение ключа (DecreaseKey) 59 23 21 39 18 38 4124 30 5 17 52 7 26 15 z y  Выполняем FibHeapCascadingCut(<26>) o Изменяем значение <26>.mark с FALSE на TRUE
  • 60. Уменьшение ключа (DecreaseKey) 60 23 21 39 18 38 4124 30 5 17 52 7 26 15  Корректируем указатель на минимальный элемент  5 < 7, указатель не изменяется
  • 61. Удаление заданного узла (Delete) 61 function FibHeapDelete(heap, x) FibHeapDecreaseKey(heap, x, -Infinity) FibHeapDeleteMin(heap) end function
  • 62. Очередь с приоритетом (Priority queue) 62  В таблице приведены трудоемкости операций очереди с приоритетом (в худшем случае, worst case)  Символом ‘*’ отмечена амортизированная сложность операций Операция Binary heap Binomial heap Fibonacci heap Pairing heap Brodal heap FindMin Θ(1) O(logn) Θ(1)* Θ(1)* Θ(1) DeleteMin Θ(logn) Θ(logn) O(logn)* O(logn)* O(logn) Insert Θ(logn) O(logn) Θ(1)* Θ(1)* Θ(1) DecreaseKey Θ(logn) Θ(logn) Θ(1)* O(logn)* Θ(1) Merge/Union Θ(n) Ω(logn) Θ(1) Θ(1)* Θ(1)
  • 63. Задания 63  Прочитать в CLRS 3ed. § “19.2 Операции над объединяемыми пирамидами”  Разобраться с доказательством амортизированной вычислительной сложности операций (метод потенциалов)  Прочитать в CLRS 3ed. § “19.4 Оценка максимальной степени”