SlideShare a Scribd company logo
1 of 58
Download to read offline
Лекция 10Биномиальные кучи(Binomial heaps) 
КурносовМихаил Георгиевич 
E-mail: mkurnosov@gmail.com 
WWW: www.mkurnosov.net 
Курс “Алгоритмы и структуры данных” 
Сибирский государственный университет телекоммуникаций и информатики (Новосибирск) 
Осенний семестр, 2014
Значение (Value) 
Приоритет(Priority) 
Слон 
3 
Кит 
1 
Лев 
15 
Очередь с приоритетом (Priority queue) 
2 
Очередь с приоритетом (Priority queue) – это очередь, в которой элементы имеют приоритет (вес) 
Поддерживаемые операции: 
oInsert(key, value)–добавляет в очередь значение valuec приоритетом (весом, ключом) key 
oDeleteMin/DeleteMax–удаляет из очереди элемент с мин./макс. приоритетом (ключом) 
oMin/Max–возвращает элемент с мин./макс. ключом 
oDecreaseKey–изменяет значение ключа заданного элемента 
oMerge(q1, q2)–сливает две очереди в одну
Двоичная куча (Binary heap) 
3 
Двоичная куча (пирамида, сортирующее дерево, binary heap) –это двоичное дерево, удовлетворяющее следующим условиям: 
a)приоритет(ключ) любой вершины не меньше ( ≥), приоритета её потомков 
b)дерево является полным двоичным деревом (complete binary tree)– все уровни заполнены, возможно за исключением последнего 
max-heap
Двоичная куча (Binary heap) 
4 
max-heap 
Приоритет любой вершины не меньше (≥), приоритета потомков 
min-heap 
Приоритет любой вершины не больше (≤), приоритета потомков
Очередь с приоритетом (Priority queue) 
5 
В таблице приведены трудоемкости операций очереди с приоритетом (в худшем случае, worst case) 
Символом ‘*’ отмечена амортизированная сложность операций 
Операция 
Binary heap 
Binomialheap 
Fibonacci heap 
Pairing heap 
Brodalheap 
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)
Биномиальные кучи (Binomial heaps) 
6 
Биномиальная куча (Binomial heap, пирамида) – это эффективно сливаемая куча(mergeableheap) 
В биномиальной куче слияние (merge, union)двух куч выполняется за время O(logn) 
Биномиальные кучи формируются на основе биномиальных деревьев (binomial trees)
Биномиальное дерево (Binomial tree) 
7 
Биномиальное дерево Bk (Binomial tree) – это рекурсивно определяемое деревовысоты k, в котором: 
oколичество узлов равно 2k 
oколичество узлов на уровне i= 0, 1, …, k 푘 푖 = 푘! 푖!푘−푖! (количество сочетаний из k по i) 
oкорень имеетk дочерних узлов: 
−первый дочерний узел (самый левый) –дерево Bk-1 
−второй дочерний узел (второй слева) –дерево Bk-2 
−… 
−k-й дочерний узел (самый правый) –дерево B0
Биномиальное дерево (Binomial tree) 
8 
Биномиальное деревоB0(n= 20= 1) 
Биномиальное деревоB1(n= 21= 2) 
Биномиальное дерево B2 
(n= 22= 4) 
Биномиальное дерево B3 
(n= 23= 8) 
B3 
B0 
B1 
B0 
B2 
B0 
B1 
B0 
B2 
B0 
B1 
B0 
B1 
B0 
B0 
Максимальная степень узла в биномиальном деревес nвершинами равна O(logn)
Биномиальная куча (Binomial heap) 
9 
Биномиальная куча (Binomial heap) – это множество биномиальных деревьев, которые удовлетворяют свойствам биномиальных куч: 
1)каждое биномиальноедерево упорядочено (ordered) в соответствии со свойствами неубывающейили невозрастающей кучи (min-heap/max-heap): ключ узла не меньше/не больше ключа его родителя 
2)для любого целого k≥ 0в куче имеется не более одногобиномиального дерева, чей корень имеет степень k 
Биномиальная куча содержащая nузлов состоит не более чем изlog(푛)+1биномиальных деревьев
Биномиальная куча (Binomial heap) 
10 
6 
29 
14 
38 
8 
17 
11 
27 
1 
25 
12 
18 
10 
Биномиальная куча из13 узлов(упорядоченные биномиальные деревья B0, B2и B3) 
Биномиальное деревоB0(n= 20= 1) 
Биномиальное дерево B2 
(n= 22= 4) 
Биномиальное дерево B3 
(n= 23= 8)
Биномиальное дерево (Binomial tree) 
11 
Пусть биномиальная куча содержит nузлов 
Если записать nв двоичной системе исчисления, то номера ненулевых битов будут соответствовать степеням биномиальных деревьев, образующих кучу 
6 
29 
14 
38 
8 
17 
11 
27 
1 
25 
12 
18 
10 
Биномиальная куча из13 узлов (деревья B0, B2и B3) 
1310= 11012
Биномиальное дерево (Binomial tree) 
12 
Корни биномиальных деревьев биномиальной кучи хранятся в односвязном списке –списке корней(root list) 
В списке корней узлы упорядоченыпо возрастанию их степеней (степеней корней биномиальных деревьев кучи) 
6 
29 
14 
38 
8 
17 
11 
27 
1 
25 
12 
18 
10 
Биномиальная куча из13 узлов (деревья B0, B2и B3) 
1310= 11012 
Head
Узел биномиальной кучи 
13 
Каждый узел биномиальной кучи (биномиального дерева) содержит следующие поля: 
parent 
key 
value 
degree 
child 
sibling 
okey–приоритет узла (вес, ключ) 
ovalue–данные 
odegree–количество дочерних узлов 
oparent–указатель на родительский узел 
ochild–указатель на крайнийлевый дочерний узел 
osibling–указатель на правый сестринский узел
Представление биномиальных куч 
14 
6 
3 
29 
0 
14 
1 
38 
0 
8 
2 
17 
0 
11 
1 
27 
0 
1 
2 
25 
0 
12 
1 
18 
0 
10 
0 
Head 
Биномиальная куча из 13 узлов (деревья B0, B2и B3)
Поиск минимальногоузла(FindMin) 
15 
В корне каждого биномиального дерева хранится его минимальный/максимальный ключ 
Для поиска минимального/максимального элемента в биномиальной куче требуется пройти по спискуизlog(푛)+1корней 
6 
29 
14 
38 
8 
17 
11 
27 
1 
25 
12 
18 
10 
Head
Поиск минимальногоузла(FindMin) 
16 
functionBinomialHeapMin(heap) 
x = heap 
min.key= Infinity 
whilex != NULL do 
ifx.key< min.keythen 
min = x 
x = x.sibling 
end while 
returnmin 
end function 
6 
29 
14 
38 
8 
17 
11 
27 
1 
25 
12 
18 
10 
Head 
TMin= O(logn)
functionBinomialHeapMin(heap) 
x = heap 
min.key= Infinity 
whilex != NULL do 
ifx.key< min.keythen 
min = x 
x = x.sibling 
end while 
returnmin 
end function 
Поиск минимальногоузла(FindMin) 
17 
6 
29 
14 
38 
8 
17 
11 
27 
1 
25 
12 
18 
10 
Head 
Как реализовать поиск минимального/максимального ключа за время O(1)? 
Поддерживать указатель на корень дерева (узел), в котором находится экстремальный ключ 
TMin= O(logn)
Слияние куч(Union) 
18 
Для слияния (union, merge)двух куч H1и H2в новую кучу Hнеобходимо: 
1.Слить списки корней H1и H2в один упорядоченный список 
2.Восстановить свойства биномиальной кучи H 
После слияния списков корней известно, что в куче Hимеется не более двух корней с одинаковой степенью и они соседствуют
Слияние списков корней 
19 
6 
44 
10 
17 
29 
31 
48 
50 
3 
37 
18 
8 
22 
23 
24 
30 
32 
45 
55 
H2 
15 
33 
28 
41 
7 
25 
12 
H1 
Списки корней H1и H2упорядочены по возрастанию степеней узлов 
Слияние выполняется аналогично слиянию упорядоченных подмассивовв MergeSort(сортировке слиянием)
Слияние списков корней 
20 
6 
44 
10 
17 
29 
31 
48 
50 
3 
37 
18 
8 
22 
23 
24 
30 
32 
45 
55 
15 
33 
28 
41 
7 
25 
12 
H 
Списки корней H1и H2упорядочены по возрастанию степеней узлов 
Слияние выполняется аналогично слиянию упорядоченных подмассивовв MergeSort(сортировке слиянием)
Слияние списков корней 
functionBinomialHeapListMerge(h1, h2) 
h = NULL 
whileh1 != NULL && h2 != NULL do 
if h1.degree <= h2.degree then 
LinkedList_AddEnd(h, h1) 
h1 = h1.next 
else 
LinkedList_AddEnd(h, h2) 
h2 = h2.next 
end if 
end while 
whileh1 != NULL do 
LinkedList_AddEnd(h, h1) 
h1 = h1.next 
end while 
whileh2 != NULL do 
LinkedList_AddEnd(h, h2) 
h2 = h2.next 
end while 
returnh 
end function 
TListMerge=O(log(max(n1, n2))) 
21
Слияние куч (Union) 
22 
6 
44 
10 
17 
29 
31 
48 
50 
3 
37 
18 
8 
22 
23 
24 
30 
32 
45 
55 
15 
33 
28 
41 
7 
25 
12 
H 
Ситуация после слияния списков корней 
Свойство 1 биномиальной кучи выполняется 
Свойство 2 не выполняется:два дерева B0и два дерева B1 
B0 
B0 
B1 
B1 
B2 
B4
23 
Случай 3 
x.degree= next-x.degree≠next-x.sibling.degreex.key≤ next-x.key 
a 
b 
c 
prev-x 
x 
next-x 
d 
a 
b 
c 
prev-x 
x 
next-x 
d 
Bk 
Bk 
Bl 
Bk 
Bk 
Bl 
Bk+1 
x.sibling= next-x.sibling 
BinomialTreeLink(next-x, x) 
next-x = x.sibling
Случай 3 
24 
6 
44 
10 
17 
29 
31 
48 
50 
3 
37 
18 
8 
22 
23 
24 
30 
32 
45 
55 
15 
33 
28 
41 
7 
25 
12 
H 
x.degree= next-x.degree≠ next-x.sibling.degreex.key≤ next-x.key 
Деревья xи next-xсвязываются 
Узел next-xстановитсялевым дочерним узлом x 
x 
next-x
x.sibling= next-x.sibling 
BinomialTreeLink(next-x, x) 
next-x = x.sibling 
Случай 3 
25 
6 
44 
10 
17 
29 
31 
48 
50 
3 
37 
18 
8 
22 
23 
24 
30 
32 
45 
55 
15 
33 
28 
41 
7 
25 
12 
H 
x 
next-x 
x.degree= next-x.degree≠ next-x.sibling.degreex.key≤ next-x.key
Связывание биномиальных деревьев 
26 
functionBinomialTreeLink(child, parent) 
child.parent= parent 
child.sibling= parent.child 
parent.child= child 
parent.degree= parent.degree+ 1 
end function 
TTreeLink= O(1) 
10 
0 
parent 
child 
z.child
Случай 2 
27 
a 
b 
c 
prev-x 
x 
next-x 
d 
a 
b 
c 
prev-x 
x 
next-x 
d 
Bk 
Bk 
Bk 
Bk 
Bk 
Bk 
x.degree= next-x.degree=next-x.sibling.degree 
/* Перемещаем указатели по списку корней */ 
prev-x = x 
x = next-x 
next-x = x.sibling
Случай 2 
28 
x.degree= next-x.degree=next-x.sibling.degree 
/* Перемещаем указатели по списку корней */ 
prev-x = x 
x = next-x 
next-x = x.sibling 
6 
44 
10 
17 
29 
31 
48 
50 
3 
37 
18 
8 
22 
23 
24 
30 
32 
45 
55 
15 
33 
28 
41 
7 
25 
12 
H 
x 
next-x 
prev-x
29 
prev-x.sibling= next-x 
BinomialTreeLink(x, next-x) 
x= next-x 
next-x = x.sibling 
Случай 4 
x.degree= next-x.degree≠next-x.sibling.degreex.key> next-x.key 
a 
b 
c 
prev-x 
x 
next-x 
d 
a 
c 
b 
prev-x 
x 
next-x 
d 
Bk 
Bk 
Bl 
Bk 
Bk 
Bl 
Bk+1
Случай 1 
30 
x.degree≠ next-x.degree 
Узел x–корень дерева Bk 
Узел next-x–корень дерева Bl, l> k 
/* Перемещаем указатели по списку корней */ 
prev-x = x 
x = next-x 
next-x = x.sibling 
a 
b 
c 
prev-x 
x 
next-x 
d 
a 
b 
c 
prev-x 
x 
next-x 
d 
Bk 
Bl 
Bk 
Bl 
l> k
Слияние биномиальных куч(Union) 
functionBinomialHeapUnion(h1, h2) 
h = BinomialHeapListMerge(h1, h2) 
prev-x = NULL 
x = h 
next-x = x.sibling 
whilenext-x != NULL do 
if(x.degree!= next-x.degree) OR 
(next-x.sibling!= NULL AND 
next-x.sibling.degree= x.degree) 
then 
prev-x = x /* Случаи 1 и 2 */ 
x = next-x 
else if x.key<= next-x.keythen 
x.sibling= next-x.sibling/* Случай 3 */ 
BinomialTreeLink(next-x, x) 
31
Слияние биномиальных куч(Union) 
else 
/* Случай 4*/ 
ifprev-x = NULL then 
h = next-x 
else 
prev-x.sibling= next-x 
end if 
BinomialTreeLink(x, next-x) 
x = next-x 
end if 
next-x = x.sibling 
end while 
returnh 
end function 
32 
TUnion= O(logn)
Слияние биномиальных куч(Union) 
33 
Вычислительная сложность слияния двух биномиальных куч в худшем случае равна O(log(n)) 
Длина списка корней не превышает 
log(n1) + log(n1) + 2 = O(log(n)) 
Цикл while в функции BinomialHeapUnionвыполняется не более O(log(n)) раз 
На каждой итерации цикла указатель перемещается по списку корней вправо на одну позицию или удаляется один узел –это требует времени O(1)
Вставка узла(Insert) 
34 
Создаем биномиальную кучу из одного узла x– биномиального дерева B0 
Сливаем исходную кучу Hи кучу из узла x 
functionBinomialHeapInsert(h, key, value) 
x.key= key 
x.value= value 
x.degree= 0 
x.parent= NULL 
x.child= NULL 
x.sibling= NULL 
returnBinomialHeapUnion(h, x) 
end function 
TInsert= O(logn)
Удаление минимального узла (DeleteMin) 
35 
1.В списке корней кучи Hотыскиваем корень xс минимальным ключом и удаляем xиз списка корней (разрывам связь) 
2.Инициализируем пустую кучу Z 
3.Меняем порядок следования дочерних узлов корня хна обратный, у каждого дочернего узла устанавливаем поле parent в NULL 
4.Устанавливаем заголовок кучи Zна первый элемент нового списка корней 
5.Сливаем кучи Hи Z 
6.Возвращаем x
Удаление минимального узла (DeleteMin) 
36 
1 
25 
12 
18 
16 
33 
26 
42 
37 
41 
6 
29 
14 
38 
8 
17 
11 
27 
10 
13 
28 
77 
H 
В списке корней кучи Hотыскиваем корень xс минимальным ключом и удаляем xиз списка корней (разрывам связь) 
x
Удаление минимального узла (DeleteMin) 
37 
1 
25 
12 
18 
16 
33 
26 
42 
37 
41 
6 
29 
14 
38 
8 
17 
11 
27 
10 
13 
28 
77 
H 
Меняем порядок следования дочерних узлов корня хна обратный, у каждого дочернего узла устанавливаем поле parent в NULL 
Дочерние узлы корня xобразуют биномиальную кучу Z 
x
Удаление минимального узла (DeleteMin) 
38 
25 
12 
18 
16 
33 
26 
42 
37 
41 
6 
29 
14 
38 
8 
17 
11 
27 
10 
13 
28 
77 
H 
Сливаем кучи Hи Z 
Z
Удаление минимального узла (DeleteMin) 
functionBinomialHeapDeleteMin(h) 
/* Lookup and unlink min node */ 
x = h 
xmin.key= Infinity 
prev= NULL 
whilex != NULL do 
ifx.key< xmin.keythen 
xmin= x 
prevmin= prev 
end if 
prev= x 
x = x.sibling 
end while 
ifprevmin!= NULL then 
prevmin.sibling= xmin.sibling 
else 
h = xmin.sibling 
39
Удаление минимального узла (DeleteMin) 
/* Reverse linked list */ 
child = xmin.child 
prev= NULL 
whilechild != NULL do 
sibling = child.sibling 
child.sibling= prev 
prev= child 
child = sibling 
end while 
returnBinomialHeapUnion(h, prev) 
end function 
40 
TDeleteMin= O(logn)
Уменьшение ключа (DecreaseKey) 
41 
1.Получаем указатель на узел xи изменяем у него ключ (newkey<= x.key) 
2.Проверяем значение ключа родительского узла, если он меньше ключа x, то выполняем обмен ключей(и данных), повторяем обмены пока не поднимемся до корня текущего биномиального дерева 
6 
29 
14 
38 
8 
17 
5 
27 
1 
25 
12 
18 
10 
Head 
x 
p
Уменьшение ключа (DecreaseKey) 
42 
functionBinomialHeapDecreaseKey(h, x, key) 
ifx.key< k then 
returnError 
x.key= key 
y = x 
z = y.parent 
whilez != NULL ANDy.key< z.keydo 
temp = y.key 
y.key= z.key 
z.key= temp 
y = z 
z = y.parent 
end while 
end function 
TDecreaseKey= O(logn)
Удаление узла (Delete) 
43 
functionBinomialHeapDelete(h, x) 
BinomialHeapDecreaseKey(h, x, -Infinity) 
BinomialHeapDeleteMin(h) 
end function 
TDelete= O(logn)
Узел биномиального дерева 
structbmheap{ 
intkey; 
char*value; 
intdegree; 
structbmheap*parent; 
structbmheap*child; 
structbmheap*sibling; 
}; 
44
Пример использования bmheap 
intmain() 
{ 
structbmheap*h = NULL, *node; 
h = bmheap_insert(h, 10, “10”); 
h = bmheap_insert(h, 12, “12”); 
h = bmheap_insert(h, 3, “3”); 
h = bmheap_insert(h, 56, “56”); 
node = bmheap_min(h); 
printf("Min = %dn", node->key); 
h = bmheap_deletemin(h); 
bmheap_free(h); 
return0; 
} 
45
Создание узла биномиального дерева 
structbmheap*bmheap_create(intkey, char*value) 
{ 
structbmheap*h; 
h = (structbmheap*)malloc(sizeof(*h)); 
if(h != NULL) { 
h->key = key; 
h->value = value; 
h->degree = 0; 
h->parent = NULL; 
h->child = NULL; 
h->sibling = NULL; 
} 
returnh; 
} 
46
Поиск минимального элемента 
structbmheap*bmheap_min(structbmheap*h) 
{ 
structbmheap*minnode, *node; 
intminkey= ~0U >> 1; /* INT_MAX */ 
for(node = h; node != NULL; 
node = node->sibling) 
{ 
if(node->key < minkey) { 
minkey= node->key; 
minnode= node; 
} 
} 
returnminnode; 
} 
47
Слияние биномиальных куч 
structbmheap*bmheap_union(structbmheap*a,structbmheap*b) 
{ 
structbmheap*h, *prevx, *x, *nextx; 
h = bmheap_mergelists(a, b); 
prevx= NULL; 
x = h; 
nextx= h->sibling; 
while(nextx!= NULL) { 
if((x->degree != nextx->degree) || 
(nextx->sibling != NULL && 
nextx->sibling->degree == x->degree)) 
{ 
/* Cases 1 & 2 */ 
prevx= x; 
x = nextx; 
} 
48
Слияние биномиальных куч 
else if (x->key <= nextx->key) { 
/* Case 3 */ 
x->sibling = nextx->sibling; 
bmheap_linktrees(nextx, x); 
} else{ 
/* Case 4 */ 
if(prevx== NULL) { 
h = nextx; 
} else{ 
prevx->sibling = nextx; 
} 
bmheap_linktrees(x, nextx); 
x = nextx; 
} 
nextx= x->sibling; 
} 
returnh; 
} 
49
Слияние списков корней 
structbmheap*bmheap_mergelists(structbmheap*a, 
structbmheap*b) 
{ 
structbmheap*head, *sibling, *end; 
end = head = NULL; 
while(a != NULL && b != NULL) { 
if(a->degree < b->degree) { 
sibling = a->sibling; 
if(end == NULL) { 
end = a; 
head = a; 
} else{ 
end->sibling = a;/* Add to the end */ 
end = a; 
a->sibling = NULL; 
} 
a = sibling; 
} 
50
Слияние списков корней 
else{ 
sibling = b->sibling; 
if(end == NULL) { 
end = b; 
head = b; 
} else{ 
end->sibling = b; /* Add to the end */ 
end = b; 
b->sibling = NULL; 
} 
b = sibling; 
} 
} 
51
Слияние списков корней 
while(a != NULL) { 
sibling = a->sibling; 
if(end == NULL) { 
end = a; 
} else{ 
end->sibling = a; 
end = a; 
a->sibling = NULL; 
} 
a = sibling; 
} 
52
Слияние списков корней 
while(b != NULL) { 
sibling = b->sibling; 
if(end == NULL) { 
end = b; 
} else{ 
end->sibling = b; 
end = b; 
b->sibling = NULL; 
} 
b = sibling; 
} 
returnhead; 
} 
53
Связывание деревьев 
voidbmheap_linktrees(structbmheap*y, 
structbmheap*z) 
{ 
y->parent = z; 
y->sibling = z->child; 
z->child = y; 
z->degree++; 
} 
54
Вставка элемента в биномиальную кучу 
structbmheap*bmheap_insert(structbmheap*h, 
intkey, char*value) 
{ 
structbmheap*node; 
if((node = bmheap_create(key, value)) == NULL) 
returnNULL; 
if(h == NULL) 
returnnode; 
returnbmheap_union(h, node); 
} 
55
Удаление минимального элемента 
structbmheap*bmheap_deletemin(structbmheap*h) 
{ 
structbmheap*x, *prev, *xmin, *prevmin, 
*child, *sibling; 
intminkey= ~0U >> 1;/* INT_MAX */ 
/* Lookup and unlink min node */ 
x = h; 
prev= NULL; 
while(x != NULL) { 
if(x->key < minkey) { 
minkey= x->key; 
xmin= x; 
prevmin= prev; 
} 
prev= x; 
x = x->sibling; 
} 
56
Удаление минимального элемента 
if(prevmin!= NULL) 
prevmin->sibling = xmin->sibling; 
else 
h = xmin->sibling; 
/* Reverse linked list */ 
child = xmin->child; 
prev= NULL; 
while(child != NULL) { 
sibling = child->sibling; 
child->sibling = prev; 
prev= child; 
child = sibling; 
} 
free(xmin); 
returnbmheap_union(h, prev); 
} 
57
Задания 
58 
Прочитать о левосторонней очереди (Leftist heap) 
Прочитать о скошенной очереди (Skew heap) 
Прочитать о куче Бродала(Brodalheap)

More Related Content

What's hot

Лекция 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
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. Очередь
Mikhail Kurnosov
 
Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)
Mikhail Kurnosov
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
Mikhail Kurnosov
 
Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)
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
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные списки
Mikhail Kurnosov
 

What's hot (20)

Лекция 7: Бинарные кучи (пирамиды)
Лекция 7: Бинарные кучи (пирамиды)Лекция 7: Бинарные кучи (пирамиды)
Лекция 7: Бинарные кучи (пирамиды)
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
 
Лекция 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)
 
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
Лекция 8: Дерево Ван Эмде Боаса (Van Emde Boas tree)
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. Очередь
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
 
Лекция 4. Префиксные деревья (Tries, prefix trees)
Лекция 4. Префиксные деревья (Tries, prefix trees)Лекция 4. Префиксные деревья (Tries, prefix trees)
Лекция 4. Префиксные деревья (Tries, prefix trees)
 
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 7. Декартовы деревья (Treaps, дучи, дерамиды)
 
Лекция 5. Бинарные деревья поиска
Лекция 5. Бинарные деревья поискаЛекция 5. Бинарные деревья поиска
Лекция 5. Бинарные деревья поиска
 
Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)Лекция 4: Префиксные деревья (Tries, prefix trees)
Лекция 4: Префиксные деревья (Tries, prefix trees)
 
Лекция 4. Стеки и очереди
Лекция 4. Стеки и очередиЛекция 4. Стеки и очереди
Лекция 4. Стеки и очереди
 
Лекция 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)
 
Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)Лекция 3. АВЛ-деревья (AVL trees)
Лекция 3. АВЛ-деревья (AVL trees)
 
Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмов
 
Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)
Лекция 9: Декартовы деревья (Treaps, дучи, дерамиды)
 
Лекция 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)
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные списки
 
Лекция 11. Деревья отрезков (Interval trees)
Лекция 11. Деревья отрезков (Interval trees)Лекция 11. Деревья отрезков (Interval trees)
Лекция 11. Деревья отрезков (Interval trees)
 
Лекция 2. Алгоритмы сортировки
Лекция 2. Алгоритмы сортировкиЛекция 2. Алгоритмы сортировки
Лекция 2. Алгоритмы сортировки
 

Viewers also liked

Лекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимостиЛекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимости
Mikhail Kurnosov
 
Лекция 12: Трудноразрешимые задачи
Лекция 12: Трудноразрешимые задачиЛекция 12: Трудноразрешимые задачи
Лекция 12: Трудноразрешимые задачи
Mikhail Kurnosov
 
Лекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмовЛекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмов
Mikhail Kurnosov
 

Viewers also liked (14)

Лекция 8. Деревья разбиения пространства (BSP tree, k-d tree, quadtree)
Лекция 8. Деревья разбиения пространства (BSP tree, k-d tree, quadtree)Лекция 8. Деревья разбиения пространства (BSP tree, k-d tree, quadtree)
Лекция 8. Деревья разбиения пространства (BSP tree, k-d tree, quadtree)
 
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
Лекция 2. Красно-чёрные деревья (Red-black trees). Скошенные деревья (Splay t...
 
Лекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимостиЛекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимости
 
Лекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графеЛекция 9. Поиск кратчайшего пути в графе
Лекция 9. Поиск кратчайшего пути в графе
 
Лекция 12: Трудноразрешимые задачи
Лекция 12: Трудноразрешимые задачиЛекция 12: Трудноразрешимые задачи
Лекция 12: Трудноразрешимые задачи
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)
 
Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)Семинар 10. Параллельное программирование на MPI (часть 3)
Семинар 10. Параллельное программирование на MPI (часть 3)
 
Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)Лекция 1. Амортизационный анализ (amortized analysis)
Лекция 1. Амортизационный анализ (amortized analysis)
 
Лекция 1. Амортизационный анализ (Amortized analysis)
Лекция 1. Амортизационный анализ (Amortized analysis)Лекция 1. Амортизационный анализ (Amortized analysis)
Лекция 1. Амортизационный анализ (Amortized analysis)
 
Лекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графовЛекция 8. Графы. Обходы графов
Лекция 8. Графы. Обходы графов
 
Лекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмовЛекция 11: Методы разработки алгоритмов
Лекция 11: Методы разработки алгоритмов
 
Лекция 12. Вероятностный анализ и рандомизированные алгоритмы (Randomized al...
Лекция 12. Вероятностный анализ и рандомизированные алгоритмы (Randomized al...Лекция 12. Вероятностный анализ и рандомизированные алгоритмы (Randomized al...
Лекция 12. Вероятностный анализ и рандомизированные алгоритмы (Randomized al...
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимости
 
Лекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицыЛекция 6. Хеш-таблицы
Лекция 6. Хеш-таблицы
 

More from Mikhail Kurnosov

More from Mikhail Kurnosov (15)

Векторизация кода (семинар 2)
Векторизация кода (семинар 2)Векторизация кода (семинар 2)
Векторизация кода (семинар 2)
 
Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Векторизация кода (семинар 3)
Векторизация кода (семинар 3)
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)
 
Лекция 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...
 
Лекция 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...
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)
 
Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)Семинар 9. Параллельное программирование на MPI (часть 2)
Семинар 9. Параллельное программирование на MPI (часть 2)
 
Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)
 
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 

Лекция 10. Биномиальные кучи (Binomial heaps)

  • 1. Лекция 10Биномиальные кучи(Binomial heaps) КурносовМихаил Георгиевич E-mail: mkurnosov@gmail.com WWW: www.mkurnosov.net Курс “Алгоритмы и структуры данных” Сибирский государственный университет телекоммуникаций и информатики (Новосибирск) Осенний семестр, 2014
  • 2. Значение (Value) Приоритет(Priority) Слон 3 Кит 1 Лев 15 Очередь с приоритетом (Priority queue) 2 Очередь с приоритетом (Priority queue) – это очередь, в которой элементы имеют приоритет (вес) Поддерживаемые операции: oInsert(key, value)–добавляет в очередь значение valuec приоритетом (весом, ключом) key oDeleteMin/DeleteMax–удаляет из очереди элемент с мин./макс. приоритетом (ключом) oMin/Max–возвращает элемент с мин./макс. ключом oDecreaseKey–изменяет значение ключа заданного элемента oMerge(q1, q2)–сливает две очереди в одну
  • 3. Двоичная куча (Binary heap) 3 Двоичная куча (пирамида, сортирующее дерево, binary heap) –это двоичное дерево, удовлетворяющее следующим условиям: a)приоритет(ключ) любой вершины не меньше ( ≥), приоритета её потомков b)дерево является полным двоичным деревом (complete binary tree)– все уровни заполнены, возможно за исключением последнего max-heap
  • 4. Двоичная куча (Binary heap) 4 max-heap Приоритет любой вершины не меньше (≥), приоритета потомков min-heap Приоритет любой вершины не больше (≤), приоритета потомков
  • 5. Очередь с приоритетом (Priority queue) 5 В таблице приведены трудоемкости операций очереди с приоритетом (в худшем случае, worst case) Символом ‘*’ отмечена амортизированная сложность операций Операция Binary heap Binomialheap Fibonacci heap Pairing heap Brodalheap 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. Биномиальные кучи (Binomial heaps) 6 Биномиальная куча (Binomial heap, пирамида) – это эффективно сливаемая куча(mergeableheap) В биномиальной куче слияние (merge, union)двух куч выполняется за время O(logn) Биномиальные кучи формируются на основе биномиальных деревьев (binomial trees)
  • 7. Биномиальное дерево (Binomial tree) 7 Биномиальное дерево Bk (Binomial tree) – это рекурсивно определяемое деревовысоты k, в котором: oколичество узлов равно 2k oколичество узлов на уровне i= 0, 1, …, k 푘 푖 = 푘! 푖!푘−푖! (количество сочетаний из k по i) oкорень имеетk дочерних узлов: −первый дочерний узел (самый левый) –дерево Bk-1 −второй дочерний узел (второй слева) –дерево Bk-2 −… −k-й дочерний узел (самый правый) –дерево B0
  • 8. Биномиальное дерево (Binomial tree) 8 Биномиальное деревоB0(n= 20= 1) Биномиальное деревоB1(n= 21= 2) Биномиальное дерево B2 (n= 22= 4) Биномиальное дерево B3 (n= 23= 8) B3 B0 B1 B0 B2 B0 B1 B0 B2 B0 B1 B0 B1 B0 B0 Максимальная степень узла в биномиальном деревес nвершинами равна O(logn)
  • 9. Биномиальная куча (Binomial heap) 9 Биномиальная куча (Binomial heap) – это множество биномиальных деревьев, которые удовлетворяют свойствам биномиальных куч: 1)каждое биномиальноедерево упорядочено (ordered) в соответствии со свойствами неубывающейили невозрастающей кучи (min-heap/max-heap): ключ узла не меньше/не больше ключа его родителя 2)для любого целого k≥ 0в куче имеется не более одногобиномиального дерева, чей корень имеет степень k Биномиальная куча содержащая nузлов состоит не более чем изlog(푛)+1биномиальных деревьев
  • 10. Биномиальная куча (Binomial heap) 10 6 29 14 38 8 17 11 27 1 25 12 18 10 Биномиальная куча из13 узлов(упорядоченные биномиальные деревья B0, B2и B3) Биномиальное деревоB0(n= 20= 1) Биномиальное дерево B2 (n= 22= 4) Биномиальное дерево B3 (n= 23= 8)
  • 11. Биномиальное дерево (Binomial tree) 11 Пусть биномиальная куча содержит nузлов Если записать nв двоичной системе исчисления, то номера ненулевых битов будут соответствовать степеням биномиальных деревьев, образующих кучу 6 29 14 38 8 17 11 27 1 25 12 18 10 Биномиальная куча из13 узлов (деревья B0, B2и B3) 1310= 11012
  • 12. Биномиальное дерево (Binomial tree) 12 Корни биномиальных деревьев биномиальной кучи хранятся в односвязном списке –списке корней(root list) В списке корней узлы упорядоченыпо возрастанию их степеней (степеней корней биномиальных деревьев кучи) 6 29 14 38 8 17 11 27 1 25 12 18 10 Биномиальная куча из13 узлов (деревья B0, B2и B3) 1310= 11012 Head
  • 13. Узел биномиальной кучи 13 Каждый узел биномиальной кучи (биномиального дерева) содержит следующие поля: parent key value degree child sibling okey–приоритет узла (вес, ключ) ovalue–данные odegree–количество дочерних узлов oparent–указатель на родительский узел ochild–указатель на крайнийлевый дочерний узел osibling–указатель на правый сестринский узел
  • 14. Представление биномиальных куч 14 6 3 29 0 14 1 38 0 8 2 17 0 11 1 27 0 1 2 25 0 12 1 18 0 10 0 Head Биномиальная куча из 13 узлов (деревья B0, B2и B3)
  • 15. Поиск минимальногоузла(FindMin) 15 В корне каждого биномиального дерева хранится его минимальный/максимальный ключ Для поиска минимального/максимального элемента в биномиальной куче требуется пройти по спискуизlog(푛)+1корней 6 29 14 38 8 17 11 27 1 25 12 18 10 Head
  • 16. Поиск минимальногоузла(FindMin) 16 functionBinomialHeapMin(heap) x = heap min.key= Infinity whilex != NULL do ifx.key< min.keythen min = x x = x.sibling end while returnmin end function 6 29 14 38 8 17 11 27 1 25 12 18 10 Head TMin= O(logn)
  • 17. functionBinomialHeapMin(heap) x = heap min.key= Infinity whilex != NULL do ifx.key< min.keythen min = x x = x.sibling end while returnmin end function Поиск минимальногоузла(FindMin) 17 6 29 14 38 8 17 11 27 1 25 12 18 10 Head Как реализовать поиск минимального/максимального ключа за время O(1)? Поддерживать указатель на корень дерева (узел), в котором находится экстремальный ключ TMin= O(logn)
  • 18. Слияние куч(Union) 18 Для слияния (union, merge)двух куч H1и H2в новую кучу Hнеобходимо: 1.Слить списки корней H1и H2в один упорядоченный список 2.Восстановить свойства биномиальной кучи H После слияния списков корней известно, что в куче Hимеется не более двух корней с одинаковой степенью и они соседствуют
  • 19. Слияние списков корней 19 6 44 10 17 29 31 48 50 3 37 18 8 22 23 24 30 32 45 55 H2 15 33 28 41 7 25 12 H1 Списки корней H1и H2упорядочены по возрастанию степеней узлов Слияние выполняется аналогично слиянию упорядоченных подмассивовв MergeSort(сортировке слиянием)
  • 20. Слияние списков корней 20 6 44 10 17 29 31 48 50 3 37 18 8 22 23 24 30 32 45 55 15 33 28 41 7 25 12 H Списки корней H1и H2упорядочены по возрастанию степеней узлов Слияние выполняется аналогично слиянию упорядоченных подмассивовв MergeSort(сортировке слиянием)
  • 21. Слияние списков корней functionBinomialHeapListMerge(h1, h2) h = NULL whileh1 != NULL && h2 != NULL do if h1.degree <= h2.degree then LinkedList_AddEnd(h, h1) h1 = h1.next else LinkedList_AddEnd(h, h2) h2 = h2.next end if end while whileh1 != NULL do LinkedList_AddEnd(h, h1) h1 = h1.next end while whileh2 != NULL do LinkedList_AddEnd(h, h2) h2 = h2.next end while returnh end function TListMerge=O(log(max(n1, n2))) 21
  • 22. Слияние куч (Union) 22 6 44 10 17 29 31 48 50 3 37 18 8 22 23 24 30 32 45 55 15 33 28 41 7 25 12 H Ситуация после слияния списков корней Свойство 1 биномиальной кучи выполняется Свойство 2 не выполняется:два дерева B0и два дерева B1 B0 B0 B1 B1 B2 B4
  • 23. 23 Случай 3 x.degree= next-x.degree≠next-x.sibling.degreex.key≤ next-x.key a b c prev-x x next-x d a b c prev-x x next-x d Bk Bk Bl Bk Bk Bl Bk+1 x.sibling= next-x.sibling BinomialTreeLink(next-x, x) next-x = x.sibling
  • 24. Случай 3 24 6 44 10 17 29 31 48 50 3 37 18 8 22 23 24 30 32 45 55 15 33 28 41 7 25 12 H x.degree= next-x.degree≠ next-x.sibling.degreex.key≤ next-x.key Деревья xи next-xсвязываются Узел next-xстановитсялевым дочерним узлом x x next-x
  • 25. x.sibling= next-x.sibling BinomialTreeLink(next-x, x) next-x = x.sibling Случай 3 25 6 44 10 17 29 31 48 50 3 37 18 8 22 23 24 30 32 45 55 15 33 28 41 7 25 12 H x next-x x.degree= next-x.degree≠ next-x.sibling.degreex.key≤ next-x.key
  • 26. Связывание биномиальных деревьев 26 functionBinomialTreeLink(child, parent) child.parent= parent child.sibling= parent.child parent.child= child parent.degree= parent.degree+ 1 end function TTreeLink= O(1) 10 0 parent child z.child
  • 27. Случай 2 27 a b c prev-x x next-x d a b c prev-x x next-x d Bk Bk Bk Bk Bk Bk x.degree= next-x.degree=next-x.sibling.degree /* Перемещаем указатели по списку корней */ prev-x = x x = next-x next-x = x.sibling
  • 28. Случай 2 28 x.degree= next-x.degree=next-x.sibling.degree /* Перемещаем указатели по списку корней */ prev-x = x x = next-x next-x = x.sibling 6 44 10 17 29 31 48 50 3 37 18 8 22 23 24 30 32 45 55 15 33 28 41 7 25 12 H x next-x prev-x
  • 29. 29 prev-x.sibling= next-x BinomialTreeLink(x, next-x) x= next-x next-x = x.sibling Случай 4 x.degree= next-x.degree≠next-x.sibling.degreex.key> next-x.key a b c prev-x x next-x d a c b prev-x x next-x d Bk Bk Bl Bk Bk Bl Bk+1
  • 30. Случай 1 30 x.degree≠ next-x.degree Узел x–корень дерева Bk Узел next-x–корень дерева Bl, l> k /* Перемещаем указатели по списку корней */ prev-x = x x = next-x next-x = x.sibling a b c prev-x x next-x d a b c prev-x x next-x d Bk Bl Bk Bl l> k
  • 31. Слияние биномиальных куч(Union) functionBinomialHeapUnion(h1, h2) h = BinomialHeapListMerge(h1, h2) prev-x = NULL x = h next-x = x.sibling whilenext-x != NULL do if(x.degree!= next-x.degree) OR (next-x.sibling!= NULL AND next-x.sibling.degree= x.degree) then prev-x = x /* Случаи 1 и 2 */ x = next-x else if x.key<= next-x.keythen x.sibling= next-x.sibling/* Случай 3 */ BinomialTreeLink(next-x, x) 31
  • 32. Слияние биномиальных куч(Union) else /* Случай 4*/ ifprev-x = NULL then h = next-x else prev-x.sibling= next-x end if BinomialTreeLink(x, next-x) x = next-x end if next-x = x.sibling end while returnh end function 32 TUnion= O(logn)
  • 33. Слияние биномиальных куч(Union) 33 Вычислительная сложность слияния двух биномиальных куч в худшем случае равна O(log(n)) Длина списка корней не превышает log(n1) + log(n1) + 2 = O(log(n)) Цикл while в функции BinomialHeapUnionвыполняется не более O(log(n)) раз На каждой итерации цикла указатель перемещается по списку корней вправо на одну позицию или удаляется один узел –это требует времени O(1)
  • 34. Вставка узла(Insert) 34 Создаем биномиальную кучу из одного узла x– биномиального дерева B0 Сливаем исходную кучу Hи кучу из узла x functionBinomialHeapInsert(h, key, value) x.key= key x.value= value x.degree= 0 x.parent= NULL x.child= NULL x.sibling= NULL returnBinomialHeapUnion(h, x) end function TInsert= O(logn)
  • 35. Удаление минимального узла (DeleteMin) 35 1.В списке корней кучи Hотыскиваем корень xс минимальным ключом и удаляем xиз списка корней (разрывам связь) 2.Инициализируем пустую кучу Z 3.Меняем порядок следования дочерних узлов корня хна обратный, у каждого дочернего узла устанавливаем поле parent в NULL 4.Устанавливаем заголовок кучи Zна первый элемент нового списка корней 5.Сливаем кучи Hи Z 6.Возвращаем x
  • 36. Удаление минимального узла (DeleteMin) 36 1 25 12 18 16 33 26 42 37 41 6 29 14 38 8 17 11 27 10 13 28 77 H В списке корней кучи Hотыскиваем корень xс минимальным ключом и удаляем xиз списка корней (разрывам связь) x
  • 37. Удаление минимального узла (DeleteMin) 37 1 25 12 18 16 33 26 42 37 41 6 29 14 38 8 17 11 27 10 13 28 77 H Меняем порядок следования дочерних узлов корня хна обратный, у каждого дочернего узла устанавливаем поле parent в NULL Дочерние узлы корня xобразуют биномиальную кучу Z x
  • 38. Удаление минимального узла (DeleteMin) 38 25 12 18 16 33 26 42 37 41 6 29 14 38 8 17 11 27 10 13 28 77 H Сливаем кучи Hи Z Z
  • 39. Удаление минимального узла (DeleteMin) functionBinomialHeapDeleteMin(h) /* Lookup and unlink min node */ x = h xmin.key= Infinity prev= NULL whilex != NULL do ifx.key< xmin.keythen xmin= x prevmin= prev end if prev= x x = x.sibling end while ifprevmin!= NULL then prevmin.sibling= xmin.sibling else h = xmin.sibling 39
  • 40. Удаление минимального узла (DeleteMin) /* Reverse linked list */ child = xmin.child prev= NULL whilechild != NULL do sibling = child.sibling child.sibling= prev prev= child child = sibling end while returnBinomialHeapUnion(h, prev) end function 40 TDeleteMin= O(logn)
  • 41. Уменьшение ключа (DecreaseKey) 41 1.Получаем указатель на узел xи изменяем у него ключ (newkey<= x.key) 2.Проверяем значение ключа родительского узла, если он меньше ключа x, то выполняем обмен ключей(и данных), повторяем обмены пока не поднимемся до корня текущего биномиального дерева 6 29 14 38 8 17 5 27 1 25 12 18 10 Head x p
  • 42. Уменьшение ключа (DecreaseKey) 42 functionBinomialHeapDecreaseKey(h, x, key) ifx.key< k then returnError x.key= key y = x z = y.parent whilez != NULL ANDy.key< z.keydo temp = y.key y.key= z.key z.key= temp y = z z = y.parent end while end function TDecreaseKey= O(logn)
  • 43. Удаление узла (Delete) 43 functionBinomialHeapDelete(h, x) BinomialHeapDecreaseKey(h, x, -Infinity) BinomialHeapDeleteMin(h) end function TDelete= O(logn)
  • 44. Узел биномиального дерева structbmheap{ intkey; char*value; intdegree; structbmheap*parent; structbmheap*child; structbmheap*sibling; }; 44
  • 45. Пример использования bmheap intmain() { structbmheap*h = NULL, *node; h = bmheap_insert(h, 10, “10”); h = bmheap_insert(h, 12, “12”); h = bmheap_insert(h, 3, “3”); h = bmheap_insert(h, 56, “56”); node = bmheap_min(h); printf("Min = %dn", node->key); h = bmheap_deletemin(h); bmheap_free(h); return0; } 45
  • 46. Создание узла биномиального дерева structbmheap*bmheap_create(intkey, char*value) { structbmheap*h; h = (structbmheap*)malloc(sizeof(*h)); if(h != NULL) { h->key = key; h->value = value; h->degree = 0; h->parent = NULL; h->child = NULL; h->sibling = NULL; } returnh; } 46
  • 47. Поиск минимального элемента structbmheap*bmheap_min(structbmheap*h) { structbmheap*minnode, *node; intminkey= ~0U >> 1; /* INT_MAX */ for(node = h; node != NULL; node = node->sibling) { if(node->key < minkey) { minkey= node->key; minnode= node; } } returnminnode; } 47
  • 48. Слияние биномиальных куч structbmheap*bmheap_union(structbmheap*a,structbmheap*b) { structbmheap*h, *prevx, *x, *nextx; h = bmheap_mergelists(a, b); prevx= NULL; x = h; nextx= h->sibling; while(nextx!= NULL) { if((x->degree != nextx->degree) || (nextx->sibling != NULL && nextx->sibling->degree == x->degree)) { /* Cases 1 & 2 */ prevx= x; x = nextx; } 48
  • 49. Слияние биномиальных куч else if (x->key <= nextx->key) { /* Case 3 */ x->sibling = nextx->sibling; bmheap_linktrees(nextx, x); } else{ /* Case 4 */ if(prevx== NULL) { h = nextx; } else{ prevx->sibling = nextx; } bmheap_linktrees(x, nextx); x = nextx; } nextx= x->sibling; } returnh; } 49
  • 50. Слияние списков корней structbmheap*bmheap_mergelists(structbmheap*a, structbmheap*b) { structbmheap*head, *sibling, *end; end = head = NULL; while(a != NULL && b != NULL) { if(a->degree < b->degree) { sibling = a->sibling; if(end == NULL) { end = a; head = a; } else{ end->sibling = a;/* Add to the end */ end = a; a->sibling = NULL; } a = sibling; } 50
  • 51. Слияние списков корней else{ sibling = b->sibling; if(end == NULL) { end = b; head = b; } else{ end->sibling = b; /* Add to the end */ end = b; b->sibling = NULL; } b = sibling; } } 51
  • 52. Слияние списков корней while(a != NULL) { sibling = a->sibling; if(end == NULL) { end = a; } else{ end->sibling = a; end = a; a->sibling = NULL; } a = sibling; } 52
  • 53. Слияние списков корней while(b != NULL) { sibling = b->sibling; if(end == NULL) { end = b; } else{ end->sibling = b; end = b; b->sibling = NULL; } b = sibling; } returnhead; } 53
  • 54. Связывание деревьев voidbmheap_linktrees(structbmheap*y, structbmheap*z) { y->parent = z; y->sibling = z->child; z->child = y; z->degree++; } 54
  • 55. Вставка элемента в биномиальную кучу structbmheap*bmheap_insert(structbmheap*h, intkey, char*value) { structbmheap*node; if((node = bmheap_create(key, value)) == NULL) returnNULL; if(h == NULL) returnnode; returnbmheap_union(h, node); } 55
  • 56. Удаление минимального элемента structbmheap*bmheap_deletemin(structbmheap*h) { structbmheap*x, *prev, *xmin, *prevmin, *child, *sibling; intminkey= ~0U >> 1;/* INT_MAX */ /* Lookup and unlink min node */ x = h; prev= NULL; while(x != NULL) { if(x->key < minkey) { minkey= x->key; xmin= x; prevmin= prev; } prev= x; x = x->sibling; } 56
  • 57. Удаление минимального элемента if(prevmin!= NULL) prevmin->sibling = xmin->sibling; else h = xmin->sibling; /* Reverse linked list */ child = xmin->child; prev= NULL; while(child != NULL) { sibling = child->sibling; child->sibling = prev; prev= child; child = sibling; } free(xmin); returnbmheap_union(h, prev); } 57
  • 58. Задания 58 Прочитать о левосторонней очереди (Leftist heap) Прочитать о скошенной очереди (Skew heap) Прочитать о куче Бродала(Brodalheap)