Биномиальная куча — различия между версиями
(Отмена правки 9928 участника 192.168.0.2 (обсуждение)) |
|||
Строка 3: | Строка 3: | ||
'''Биномиальное дерево <tex>B_k</tex>''' {{---}} [[Дерево, эквивалентные определения|дерево]], определяемое для каждого <tex>k = 0, 1, 2, \dots </tex> следующим образом: <tex>B_0</tex> - дерево, состоящее из одного узла высоты 0, то есть состоит из одного узла; <tex>B_k</tex> состоит из двух биномиальных деревьев <tex>B_{k-1}</tex>, связанны вместе таким образом, что корень одного из них является крайним левым дочерним узлом корня второго дерева.}} | '''Биномиальное дерево <tex>B_k</tex>''' {{---}} [[Дерево, эквивалентные определения|дерево]], определяемое для каждого <tex>k = 0, 1, 2, \dots </tex> следующим образом: <tex>B_0</tex> - дерево, состоящее из одного узла высоты 0, то есть состоит из одного узла; <tex>B_k</tex> состоит из двух биномиальных деревьев <tex>B_{k-1}</tex>, связанны вместе таким образом, что корень одного из них является крайним левым дочерним узлом корня второго дерева.}} | ||
− | Пример биномиального дерева для k = 0, 2 | + | Пример биномиального дерева для k = 0, 1, 2. |
[[Файл:Example.jpg|325px|]] | [[Файл:Example.jpg|325px|]] | ||
Строка 9: | Строка 9: | ||
'''Свойства биномиальных деревьев. ''' | '''Свойства биномиальных деревьев. ''' | ||
Биномиальное дерево <tex>B_k</tex> с n вершинами: | Биномиальное дерево <tex>B_k</tex> с n вершинами: | ||
− | * | + | *имеет <tex>2^k</tex> узлов; |
+ | *имеет высоту k; | ||
+ | *имеет ровно <tex>{k\choose i}</tex> узлов на высоте <tex>i = 0, 1, 2, \dots</tex>; | ||
+ | *имеет корень степени k; степерь всех остальных вершин меньше степени корня биномиального дерева; | ||
+ | *максимальная степень произвольного узла в биномиальном дереве с n узлами равна <tex>\log(n)</tex>. | ||
+ | |||
+ | {{Определение | ||
+ | |definition= | ||
+ | '''Биномиальная пирамида ([[Двоичная куча|куча]]) H''' {{---}} представляет собой множество биномиальных деревьев, которые удовлетворяют следующим свойствам '''биномиальных пирамид'''. | ||
+ | *Каждое биномиальное дерево в Н подчиняется свойству '''неубывающей пирамиды''': ключ узла не меньше ключа его родительского узла (упорядоченное в соответствии со свойсвом неубывающей прирамиды дерево). | ||
+ | *Для любого неотрицательного целого k найдется не более одного биномиального дерева Н, чей корень имеет степень K.}} | ||
+ | |||
+ | ==== Представление биномиальных куч ==== | ||
+ | Поскольку количество детей у узлов варьируется в широких пределах, ссылка на детей осуществляется через левого ребенка, а остальные дети образуют односвязный список. Каждый узел в биномиальной пирамиде (куче) представляется набором полей: | ||
+ | *''key'' {{---}} ключ (вес) элемента; | ||
+ | *''parent'' {{---}} указатель на родителя узла; | ||
+ | *''child'' {{---}} указатель на левого ребенка узла; | ||
+ | *''sibling'' {{---}} указатель на правого брата узла; | ||
+ | *''degree'' {{---}} степень узла (количество дочерних узлов данного узла). | ||
+ | |||
+ | Корни деревьев, их которых состоит пирамида, содержатся в так называемом '''списке корней''', при проходе по которому степени соответствующих корней находятся в неубывающем порядке. | ||
+ | Доступ к куче осуществляется ссылкой на первый корень в списке корней. | ||
+ | |||
+ | == Операции над биномиальными пирамидами == | ||
+ | |||
+ | ---- | ||
+ | |||
+ | Рассмотрим операции, которые можно производить с биномиальной пирамидой. Их асимптотические оценки показаны в таблице. | ||
+ | {| border="1" | ||
+ | |Make_Heap | ||
+ | |<tex>\Theta(1)</tex> | ||
+ | |- | ||
+ | |Insert | ||
+ | |<tex>O(\log(n))</tex> | ||
+ | |- | ||
+ | |Minimum | ||
+ | |<tex>O(\log(n))</tex> | ||
+ | |- | ||
+ | |Extract_Min | ||
+ | |<tex>\Theta(\log(n))</tex> | ||
+ | |- | ||
+ | |Union | ||
+ | |<tex>\Omega(\log(n))</tex> | ||
+ | |- | ||
+ | |Decrease_Key | ||
+ | |<tex>\Theta(\log(n))</tex> | ||
+ | |- | ||
+ | |Delete | ||
+ | |<tex>\Theta(\log(n))</tex> | ||
+ | |} | ||
+ | |||
+ | === Make_Heap === | ||
+ | Для создания пустой биномиальной приамиды процедура Make_Binomial_Heap просто выделяет память и возвращает объект H, где head[H] = nil, то есть пирамида не содержит элементов. | ||
+ | |||
+ | === Minimum === | ||
+ | Для нахождения минимального элемента надо найти элемент в списке корней с минимальным значением (предполагается, что ключей, равных <tex>\infty</tex>, нет). | ||
+ | |||
+ | Асимптотика этой операции получается из того, что корней в этом списке не более <tex>\lfloor \log(n) \rfloor + 1</tex>. | ||
+ | |||
+ | При вызове этой процедуры для кучи, изображенной на картинке ниже, будет возвращен указатель на вершину с ключем 1. | ||
+ | |||
+ | [[Файл:Example2.jpg]] | ||
+ | |||
+ | === Union === | ||
+ | Эта операция, соединяющая две биномиальные кучи в одну, используется в качестве подпрограммы большинством остальных операций. | ||
+ | |||
+ | Для этого нам надо сначала слить списки корней <tex>H_1, H_2</tex> в единый связный список, отсортированный по степеням в монотонно возрастающем порядке. Свойство пирамиды обеспечивает нам в новом списке наличие не более двух деревьев одинаковой степени. Далее мы за один проход по этому списку объединим некоторые деревья так, что в результате все они будут иметь попарно разные степени. На каждом шаге нам надо расмотреть несколько случаев. | ||
+ | |||
+ | * Рассматриваемое дерево и следующее за ним имеют разные степени (случай ''a'' на рисунке). Ситуация тривиальна и не требует никаких действий. Переходим к следующему шагу. | ||
+ | * Текущее дерево и его два ближаших соседа справа (то есть те, которые встретятся на последующих итерациях) имеют одинаковые степени (случай ''b'' на рисунке). Эта ситуация хоть и не тривиальна, но ее следует оставить для следующего шага. | ||
+ | * Если степень текущего и последующего деревьев одинакова (случай ''c-d'' на рисунке), то нам следует объединить их в новое дерево (сделав корнем вершину того дерева, чей ключ наименьший), степень которого будет на единицу больше той, что была ранее. | ||
+ | |||
+ | [[Файл:Example3.jpg]] | ||
+ | |||
+ | Пример пирамиды до Union и после: | ||
+ | |||
+ | [[Файл:Example5.jpg]] | ||
+ | |||
+ | === Inset === | ||
+ | Необходимо просто создать биномиальную пирамиду <tex>H'</tex> с одним узлом за время <tex>O(1)</tex> и объединяет ее с биномиальной пирамидой Н, содержащей n узлов, за время <tex>O(\log(n))</tex>. | ||
+ | |||
+ | === Extract_Min === | ||
+ | Приведенная ниже процедура извлекает узел с минимальным ключом из биномиальной кучи и возвращает указатель на извлеченный узел: | ||
+ | |||
+ | <code> | ||
+ | Binomial_Heap_Extract_Min(H) | ||
+ | поиск корня х с минимальным значением ключа в списке корней Н, и удаление х из корней Н | ||
+ | H' = Make_Binomial_Heap() | ||
+ | Обращение порядка связанного списка дочерних узлов х, | ||
+ | установка поля р каждого дочернего узла Н равным NIL | ||
+ | присвоение указателю head[H'] адреса заголовка | ||
+ | получающегося списка | ||
+ | H = Binomial_Heap_Union(H, H') | ||
+ | return x | ||
+ | </code> | ||
+ | |||
+ | Поскольку минимальный элемент находится в корневом списке, найти его легко; после его удаления соответствующее дерево рассыпается в набор биномиальных деревьев меньшего размера, который надо объединить с оставшейся частью кучи. | ||
+ | Все действия выполняются за время <tex>O\log(n)</tex>, так что общее время работы процедуры есть <tex>O\log(n)</tex>. | ||
+ | |||
+ | === Decrease_Key === | ||
+ | Следующая процедура уменьшает ключ элемента х биномиальной кучи, присваивая ему новое значение. Вершина, ключ которой был уменьшен, «всплывает» наверх. Процедура выполняется за время <tex>O\log(n)</tex>, поскольку глубина вершины х есть <tex>O\log(n)</tex> (свойства биномиального дерева), а при выполнении каждого шага алгоритма мы поднимаемся вверх. | ||
+ | |||
+ | <code> | ||
+ | Binomial_Heap_Decrease_Key(H, x, k) | ||
+ | if k > key[x] then | ||
+ | return | ||
+ | key[x] = k | ||
+ | y = x | ||
+ | z = p[y] | ||
+ | while (z <tex>\ne</tex> NIL and key[y] < key[z]) do | ||
+ | swap(key[y], key[z]) | ||
+ | y = z | ||
+ | z = p[y] | ||
+ | </code> | ||
+ | |||
+ | Пример работы процедуры проиллюстрирован на рисунке (y - уменьшаемый элемент, z - его предок). | ||
+ | |||
+ | [[Файл:Example6.jpg|600px]] | ||
+ | |||
+ | === Delete === | ||
+ | Удаление ключа сводится к двум предыдущим операциям: мы уменьшаем ключ до минимально возможного значения, а затем удаляем вершину с минимальным ключом. В процессе выполнения процедуры это значение всплывает вверх, откуда и удаляется. Процедура выполняется за время <tex>O\log(n)</tex>. | ||
+ | |||
+ | <code> | ||
+ | Binomial_Heap_Delete(H, x) | ||
+ | Binomial_Heap_Decrease_Key(H, x, -<tex>\infty</tex>) | ||
+ | Binomial_Heap_Extract_Min(H) | ||
+ | </code> | ||
+ | |||
+ | == Источники == | ||
+ | ---- | ||
+ | * [http://www.intuit.ru/department/algorithms/dscm/7/ INTUIT.ru |Биномиальные кучи] | ||
+ | * [http://en.wikipedia.org/wiki/Binomial_heap Wikipedia | Binomial_heap] | ||
+ | * Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — 2-е изд. — М.: Издательский дом «Вильямс», 2007. — С. 538-558. |
Версия 00:41, 15 июня 2011
Определение: |
Биномиальное дерево дерево, определяемое для каждого следующим образом: - дерево, состоящее из одного узла высоты 0, то есть состоит из одного узла; состоит из двух биномиальных деревьев , связанны вместе таким образом, что корень одного из них является крайним левым дочерним узлом корня второго дерева. | —
Пример биномиального дерева для k = 0, 1, 2.
Свойства биномиальных деревьев. Биномиальное дерево
с n вершинами:- имеет узлов;
- имеет высоту k;
- имеет ровно узлов на высоте ;
- имеет корень степени k; степерь всех остальных вершин меньше степени корня биномиального дерева;
- максимальная степень произвольного узла в биномиальном дереве с n узлами равна .
Определение: |
Биномиальная пирамида (куча) H — представляет собой множество биномиальных деревьев, которые удовлетворяют следующим свойствам биномиальных пирамид.
|
Содержание
Представление биномиальных куч
Поскольку количество детей у узлов варьируется в широких пределах, ссылка на детей осуществляется через левого ребенка, а остальные дети образуют односвязный список. Каждый узел в биномиальной пирамиде (куче) представляется набором полей:
- key — ключ (вес) элемента;
- parent — указатель на родителя узла;
- child — указатель на левого ребенка узла;
- sibling — указатель на правого брата узла;
- degree — степень узла (количество дочерних узлов данного узла).
Корни деревьев, их которых состоит пирамида, содержатся в так называемом списке корней, при проходе по которому степени соответствующих корней находятся в неубывающем порядке. Доступ к куче осуществляется ссылкой на первый корень в списке корней.
Операции над биномиальными пирамидами
Рассмотрим операции, которые можно производить с биномиальной пирамидой. Их асимптотические оценки показаны в таблице.
Make_Heap | |
Insert | |
Minimum | |
Extract_Min | |
Union | |
Decrease_Key | |
Delete |
Make_Heap
Для создания пустой биномиальной приамиды процедура Make_Binomial_Heap просто выделяет память и возвращает объект H, где head[H] = nil, то есть пирамида не содержит элементов.
Minimum
Для нахождения минимального элемента надо найти элемент в списке корней с минимальным значением (предполагается, что ключей, равных
, нет).Асимптотика этой операции получается из того, что корней в этом списке не более
.При вызове этой процедуры для кучи, изображенной на картинке ниже, будет возвращен указатель на вершину с ключем 1.
Union
Эта операция, соединяющая две биномиальные кучи в одну, используется в качестве подпрограммы большинством остальных операций.
Для этого нам надо сначала слить списки корней
в единый связный список, отсортированный по степеням в монотонно возрастающем порядке. Свойство пирамиды обеспечивает нам в новом списке наличие не более двух деревьев одинаковой степени. Далее мы за один проход по этому списку объединим некоторые деревья так, что в результате все они будут иметь попарно разные степени. На каждом шаге нам надо расмотреть несколько случаев.- Рассматриваемое дерево и следующее за ним имеют разные степени (случай a на рисунке). Ситуация тривиальна и не требует никаких действий. Переходим к следующему шагу.
- Текущее дерево и его два ближаших соседа справа (то есть те, которые встретятся на последующих итерациях) имеют одинаковые степени (случай b на рисунке). Эта ситуация хоть и не тривиальна, но ее следует оставить для следующего шага.
- Если степень текущего и последующего деревьев одинакова (случай c-d на рисунке), то нам следует объединить их в новое дерево (сделав корнем вершину того дерева, чей ключ наименьший), степень которого будет на единицу больше той, что была ранее.
Пример пирамиды до Union и после:
Inset
Необходимо просто создать биномиальную пирамиду
с одним узлом за время и объединяет ее с биномиальной пирамидой Н, содержащей n узлов, за время .Extract_Min
Приведенная ниже процедура извлекает узел с минимальным ключом из биномиальной кучи и возвращает указатель на извлеченный узел:
Binomial_Heap_Extract_Min(H) поиск корня х с минимальным значением ключа в списке корней Н, и удаление х из корней Н H' = Make_Binomial_Heap() Обращение порядка связанного списка дочерних узлов х, установка поля р каждого дочернего узла Н равным NIL присвоение указателю head[H'] адреса заголовка получающегося списка H = Binomial_Heap_Union(H, H') return x
Поскольку минимальный элемент находится в корневом списке, найти его легко; после его удаления соответствующее дерево рассыпается в набор биномиальных деревьев меньшего размера, который надо объединить с оставшейся частью кучи. Все действия выполняются за время
, так что общее время работы процедуры есть .Decrease_Key
Следующая процедура уменьшает ключ элемента х биномиальной кучи, присваивая ему новое значение. Вершина, ключ которой был уменьшен, «всплывает» наверх. Процедура выполняется за время
, поскольку глубина вершины х есть (свойства биномиального дерева), а при выполнении каждого шага алгоритма мы поднимаемся вверх.
Binomial_Heap_Decrease_Key(H, x, k)
if k > key[x] then
return
key[x] = k
y = x
z = p[y]
while (z
NIL and key[y] < key[z]) do
swap(key[y], key[z])
y = z
z = p[y]
Пример работы процедуры проиллюстрирован на рисунке (y - уменьшаемый элемент, z - его предок).
Delete
Удаление ключа сводится к двум предыдущим операциям: мы уменьшаем ключ до минимально возможного значения, а затем удаляем вершину с минимальным ключом. В процессе выполнения процедуры это значение всплывает вверх, откуда и удаляется. Процедура выполняется за время
.
Binomial_Heap_Delete(H, x)
Binomial_Heap_Decrease_Key(H, x, -
)
Binomial_Heap_Extract_Min(H)
Источники
- INTUIT.ru |Биномиальные кучи
- Wikipedia | Binomial_heap
- Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — 2-е изд. — М.: Издательский дом «Вильямс», 2007. — С. 538-558.