Изменения

Перейти к: навигация, поиск

Биномиальная куча

1 байт добавлено, 02:50, 5 апреля 2011
Union
=== Union ===
Эта операция, соединяющая две биномиальные кучи в одну, используется в качестве подпрограммы большинством остальных операций.
Процедура Binomial_Heap_Union многократно связывает биномиальные деревья с корнями одинаковой степени. Приведенная далее процедура связывает дерево <tex>B_k</tex> с корнем y с деревом <tex>B_{k-1}</tex> с корнем z, делая z родительским узлом для y, после чего узел z становится корнем дерева <tex>B_k</tex>.
<code>
Binomial_Link(y, z)
p[y] = z
sibling[y] = child[z]
child[z] = y
degree[z]++
</code>
Приведенная далее процедура сливает биномиальные кучи <tex>H_1, H_2</tex>, возвращая получаемую в результате биномиальную прирамиду. <tex>H_1, H_2</tex> удаляются. Процедура Binomial_Heap_Merge сливает Для этого нам надо сначала слить списки корней <tex>H_1, H_2</tex> в единый связный список, отсортированный по степеням в монотонно возрастающем порядке. Свойство пирамиды обеспечивает нам в новом списке наличие не более двух деревьев одинаковой степени. Далее мы за один проход по этому списку объединим некоторые деревья так, что в результате все они будут иметь попарно разные степени. На каждом шаге нам надо расмотреть несколько случаев.
<code>* Рассматриваемое дерево и следующее за ним имеют разные степени (случай ''a'' на рисунке). Ситуация тривиальна и не требует никаких действий. Переходим к следующему шагу.* Текущее дерево и его два ближаших соседа справа (то есть те, которые встретятся на последующих итерациях) имеют одинаковые степени (случай ''b'' на рисунке). Эта ситуация хоть и не тривиальна, но ее следует оставить для следующего шага.* Если степень текущего и последующего деревьев одинакова (случай ''c-d'' на рисунке), то нам следует объединить их в новое дерево (сделав корнем вершину того дерева, чей ключ наименьший), степень которого будет на единицу больше той, что была ранее.
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Файл:Example3.jpg] = sibling[next_x] Binomial_Link(next_x, x) else if prev_x = NIL then head[H] = next_x else sibling[prev_x] = next_x Binomial_Link(x, next_x) x = next_x next_x = sibling[x]</code>
=== Inset ===
22
правки

Навигация