Биномиальная куча — различия между версиями
| Строка 80: | Строка 80: | ||
</code> | </code> | ||
| − | Приведенная далее процедура сливает биномиальные кучи <tex>H_1 | + | Приведенная далее процедура сливает биномиальные кучи <tex>H_1, H_2</tex>, возвращая получаемую в результате биномиальную прирамиду. <tex>H_1, H_2</tex> удаляются. Процедура Binomial_Heap_Merge сливает списки корней <tex>H_1, H_2</tex> в единый связный список, отсортированный по степеням в монотонно возрастающем порядке. |
| + | |||
| + | <code> | ||
| + | Binomial_Heap_Union(<tex>H_1, H_2</tex>) | ||
| + | H = Make_Binomial_Heap() | ||
| + | head[H] = Binomial_Heap_Merge(<tex>H_1, H_2</tex>) | ||
| + | delete <tex>H_1, H_2</tex> //удаление объектов, но не списков, на которые они указывают | ||
| + | if head[H] = NIL | ||
| + | then return H | ||
| + | prex_x = NIL | ||
| + | x = head[H] | ||
| + | next_x = sibling[x] | ||
| + | while next_x <tex>\ne</tex> NIL do | ||
| + | if (degree[x] <tex>\ne</tex> degree[next_x]) or (sibling[next_x] <tex>\ne</tex> NIL and degree[sibling[next_x]] = degree[x]) then | ||
| + | prex_x = x | ||
| + | else | ||
| + | if key[x] <= key[next_x] then | ||
| + | sibling[x] = sibling[next_x] | ||
| + | Binomial_Link(next_x, x) | ||
| + | else | ||
| + | if prev_x = NIL then | ||
| + | head[H] = next_x | ||
| + | else | ||
| + | sibling[prev_x] = next_x | ||
| + | </code> | ||
Версия 00:05, 14 марта 2011
| Определение: |
| Биномиальное дерево — дерево, определяемое для каждого следующим образом: - дерево, состоящее из одного узла высоты 0, то есть состоит из одного узла; состоит из двух биномиальных деревьев , связанны вместе таким образом, что корень одного из них является крайним левым дочерним узлом корня второго дерева. |
Свойства биномиальных деревьев. Биномиальное дерево с n вершинами:
- имеет узлов;
- имеет высоту k;
- имеет ровно узлов на высоте ;
- имеет корень степени k; степерь всех остальных вершин меньше степени корня биномиального дерева. Кроме того, если дочерние узлы корня пронумеровать слева направо числами , то i-й дочерний узел корня является корнем биномиального дерева
- максимальная степень произвольного узла в биномиальном дереве с n узлами равна .
| Определение: |
Биномиальная пирамида H — представляет собой множество биномиальных деревьев, которые удовлетворяют следующим свойствам биномиальных пирамид.
|
Содержание
Представление биномиальных куч
Поскольку количество детей у узлов варьируется в широких пределах, ссылка на детей осуществляется через левого ребенка, а остальные дети образуют односвязный список. Каждый узел в биномиальной пирамиде (куче) представляется набором полей:
- key — ключ (вес) элемента;
- parent — указатель на родителя узла;
- child — указатель на левого ребенка узла;
- sibling — указатель на правого брата узла;
- degree — степень узла (количество дочерних узлов данного узла).
Доступ к куче осуществляется ссылкой на самое левое поддерево. Корни деревьев, из которых составлена куча, оказываются организованными с помощью поля sibling в так называемый корневой односвязный список.
Операции над биномиальными пирамидами
Рассмотрим операции, которые можно производить с биномиальной пирамидой. Их верхние асимптотические оценки показаны в таблице.
| Make_Heap | |
| Insert | |
| Minimum | |
| Extract_Min | |
| Union | |
| Decrease_Key | |
| Delete |
Make_Heap
Для создания пустой биномиальной приамиды процедура Make_Binomial_Heap просто выделяет память и возвращает объект H, где head[H] = nil, то есть пирамида не содержит элементов.
Minimum
Процедура Binomial_Heap_Minimum возвращает указатель на узел с минимальным ключом. Приведенный ниже певдокод предполагает, что ключей, равных , нет.
Binomial_Yeap_Minimum(H) y = NIL x = head[H] min = while x NIL do if key[x] < min then y = x x = sibling[x] return y
Union
Эта операция, соединяющая две биномиальные кучи в одну, используется в качестве подпрограммы большинством остальных операций.
Процедура Binomial_Heap_Union многократно связывает биномиальные деревья с корнями одинаковой степени. Приведенная далее процедура связывает дерево с корнем y с деревом с корнем z, делая z родительским узлом для y, после чего узел z становится корнем дерева .
Binomial_Link(y, z) p[y] = z sibling[y] = child[z] child[z] = y degree[z]++
Приведенная далее процедура сливает биномиальные кучи , возвращая получаемую в результате биномиальную прирамиду. удаляются. Процедура Binomial_Heap_Merge сливает списки корней в единый связный список, отсортированный по степеням в монотонно возрастающем порядке.
Binomial_Heap_Union() H = Make_Binomial_Heap() head[H] = Binomial_Heap_Merge() delete //удаление объектов, но не списков, на которые они указывают if head[H] = NIL then return H prex_x = NIL x = head[H] next_x = sibling[x] while next_x NIL do if (degree[x] degree[next_x]) or (sibling[next_x] NIL and degree[sibling[next_x]] = degree[x]) then prex_x = x else if key[x] <= key[next_x] then sibling[x] = sibling[next_x] Binomial_Link(next_x, x) else if prev_x = NIL then head[H] = next_x else sibling[prev_x] = next_x