Биномиальная куча — различия между версиями
Rybak (обсуждение | вклад) (→delete) |
Gr1n (обсуждение | вклад) (→Биномиальное дерево) |
||
Строка 1: | Строка 1: | ||
= Биномиальное дерево = | = Биномиальное дерево = | ||
− | |||
{{Определение | {{Определение | ||
Строка 12: | Строка 11: | ||
== Свойства биномиальных деревьев == | == Свойства биномиальных деревьев == | ||
+ | {{Утверждение | ||
+ | |statement=Биномиальное дерево <tex>B_k</tex> с <tex>n</tex> вершинами имеет <tex>2^k</tex> узлов | ||
+ | |proof=Так как в дереве порядка <tex>k+1</tex> вдвое больше узлов, чем в дереве порядка <tex>k</tex>, а в дереве нулевого порядка <tex>1 = 2^0</tex> узел, то дерево порядка <tex>k</tex> имеет <tex>2^k</tex> узлов. | ||
+ | }} | ||
− | + | {{Утверждение | |
− | + | |statement=Биномиальное дерево <tex>B_k</tex> с <tex>n</tex> вершинами имеет высоту <tex>k</tex>; | |
− | + | |proof=Так как в дереве порядка <tex>k+1</tex> высота больше на <tex>1</tex> (так как мы подвешиваем к текущему дереву дерево того же порядка), чем в дереве порядка <tex>k</tex>, а в дереве нулевого порядка высота <tex>0</tex> , то дерево порядка <tex>k</tex> имеет высоту <tex>k</tex>. | |
− | + | }} | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | Биномиальное дерево <tex>B_k</tex> с <tex>n</tex> вершинами имеет высоту <tex>k</tex>; | ||
− | |||
− | |||
− | |||
− | Так как в дереве порядка <tex>k+1</tex> высота больше на <tex>1</tex> (так как мы подвешиваем к текущему дереву дерево того же порядка), чем в дереве порядка <tex>k</tex>, а в дереве нулевого порядка высота <tex>0</tex> , то дерево порядка <tex>k</tex> имеет высоту <tex>k</tex>. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | {{Утверждение | ||
+ | |statement=Биномиальное дерево <tex>B_k</tex> с <tex>n</tex> вершинами имеет ровно <tex>{k\choose i}</tex> узлов на высоте <tex>i = 0, 1, 2, \dots</tex>; | ||
+ | |proof= | ||
Докажем по индукции: | Докажем по индукции: | ||
Строка 40: | Строка 29: | ||
Рассмотрим <tex>i</tex> уровень дерева <tex>B_{k+1}</tex>. Дерево <tex>B_{k+1}</tex> было получено подвешиванием одного дерева порядка <tex>k</tex> к другому. Тогда на <tex>i</tex> уровне дерева <tex>B_{k+1}</tex> всего узлов <tex>{k\choose i} + {k\choose {i - 1}}</tex>, так как от подвешенного дерева в дерево порядка <tex>k+1</tex> нам пришли узлы глубины <tex>i-1</tex>. То для <tex>i</tex> уровня дерева <tex>B_{k+1}</tex> количество узлов <tex>{k\choose i} + {k\choose {i - 1}} ={{k + 1}\choose i} </tex>. То свойство доказано. | Рассмотрим <tex>i</tex> уровень дерева <tex>B_{k+1}</tex>. Дерево <tex>B_{k+1}</tex> было получено подвешиванием одного дерева порядка <tex>k</tex> к другому. Тогда на <tex>i</tex> уровне дерева <tex>B_{k+1}</tex> всего узлов <tex>{k\choose i} + {k\choose {i - 1}}</tex>, так как от подвешенного дерева в дерево порядка <tex>k+1</tex> нам пришли узлы глубины <tex>i-1</tex>. То для <tex>i</tex> уровня дерева <tex>B_{k+1}</tex> количество узлов <tex>{k\choose i} + {k\choose {i - 1}} ={{k + 1}\choose i} </tex>. То свойство доказано. | ||
+ | }} | ||
− | + | {{Утверждение | |
+ | |statement=Биномиальное дерево <tex>B_k</tex> с <tex>n</tex> вершинами имеет корень степени <tex>k</tex>; степень всех остальных вершин меньше степени корня биномиального дерева; | ||
+ | |proof=Так как в дереве порядка <tex>k+1</tex> степень корня больше на <tex>1</tex>, чем в дереве порядка <tex>k</tex>, а в дереве нулевого порядка степень корня <tex>0</tex>, то дерево порядка <tex>k</tex> имеет корень степени <tex>k</tex>. И так как при таком увеличении порядка(при переходе от дерева порядка <tex>k</tex> к <tex>k+1</tex>) в полученном дереве лишь степень корня возрастает, то доказываемый инвариант, то есть степень корня больше степени остальных вершин, не будет нарушаться. | ||
− | + | }} | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | {{Утверждение | ||
+ | |statement=Биномиальное дерево <tex>B_k</tex> с <tex>n</tex> вершинами максимальная степень произвольного узла в биномиальном дереве с <tex>n</tex> узлами равна <tex>\log(n)</tex>. | ||
+ | |proof= | ||
Докажем это утверждение для корня. Степень остальных вершин меньше по предыдущему свойству. Так как степень корня дерева порядка <tex>k</tex> равна <tex>k</tex>, а узлов в этом дереве <tex>n = 2^k</tex>, то прологарифмировав обе части получаем, что <tex>k=O(\log(n))</tex>, то степень произвольного узла не более <tex>\log(n)</tex>. | Докажем это утверждение для корня. Степень остальных вершин меньше по предыдущему свойству. Так как степень корня дерева порядка <tex>k</tex> равна <tex>k</tex>, а узлов в этом дереве <tex>n = 2^k</tex>, то прологарифмировав обе части получаем, что <tex>k=O(\log(n))</tex>, то степень произвольного узла не более <tex>\log(n)</tex>. | ||
+ | }} | ||
= Биномиальная куча= | = Биномиальная куча= |
Версия 22:26, 9 марта 2012
Содержание
Биномиальное дерево
Определение: |
Биномиальное дерево дерево, определяемое для каждого следующим образом: — дерево, состоящее из одного узла высоты , то есть состоит из одного узла; состоит из двух биномиальных деревьев , связанны вместе таким образом, что корень одного из них является крайним левым дочерним узлом корня второго дерева. | —
Свойства биномиальных деревьев
Утверждение: |
Биномиальное дерево с вершинами имеет узлов |
Так как в дереве порядка | вдвое больше узлов, чем в дереве порядка , а в дереве нулевого порядка узел, то дерево порядка имеет узлов.
Утверждение: |
Биномиальное дерево с вершинами имеет высоту ; |
Так как в дереве порядка | высота больше на (так как мы подвешиваем к текущему дереву дерево того же порядка), чем в дереве порядка , а в дереве нулевого порядка высота , то дерево порядка имеет высоту .
Утверждение: |
Биномиальное дерево с вершинами имеет ровно узлов на высоте ; |
Докажем по индукции: База Рассмотрим — верно. Пусть для некоторого условие верно, то докажем, что для это также верно: уровень дерева . Дерево было получено подвешиванием одного дерева порядка к другому. Тогда на уровне дерева всего узлов , так как от подвешенного дерева в дерево порядка нам пришли узлы глубины . То для уровня дерева количество узлов . То свойство доказано. |
Утверждение: |
Биномиальное дерево с вершинами имеет корень степени ; степень всех остальных вершин меньше степени корня биномиального дерева; |
Так как в дереве порядка | степень корня больше на , чем в дереве порядка , а в дереве нулевого порядка степень корня , то дерево порядка имеет корень степени . И так как при таком увеличении порядка(при переходе от дерева порядка к ) в полученном дереве лишь степень корня возрастает, то доказываемый инвариант, то есть степень корня больше степени остальных вершин, не будет нарушаться.
Утверждение: |
Биномиальное дерево с вершинами максимальная степень произвольного узла в биномиальном дереве с узлами равна . |
Докажем это утверждение для корня. Степень остальных вершин меньше по предыдущему свойству. Так как степень корня дерева порядка | равна , а узлов в этом дереве , то прологарифмировав обе части получаем, что , то степень произвольного узла не более .
Биномиальная куча
Определение: |
Биномиальная пирамида — представляет собой множество биномиальных деревьев, которые удовлетворяют следующим свойствам:
|
Представление биномиальных куч
Поскольку количество детей у узлов варьируется в широких пределах, ссылка на детей осуществляется через левого ребенка, а остальные дети образуют односвязный список. Каждый узел в биномиальной пирамиде (куче) представляется набором полей:
- — ключ (вес) элемента;
- — указатель на родителя узла;
- — указатель на левого ребенка узла;
- — указатель на правого брата узла;
- — степень узла (количество дочерних узлов данного узла).
Корни деревьев, их которых состоит пирамида, содержатся в так называемом списке корней, при проходе по которому степени соответствующих корней находятся в неубывающем порядке. Доступ к куче осуществляется ссылкой на первый корень в списке корней.
Операции над биномиальными кучами
Рассмотрим операции, которые можно производить с биномиальной пирамидой. Их асимптотики показаны в таблице.
insert | |
getMinimum | |
extractMin | |
merge | |
decreaseKey | |
delete |
Обозначим нашу кучу за
. То пусть — указатель на корень биномиального дерева минимального порядка этой кучи. Изначально , то есть пирамида не содержит элементов.getMinimum
Для нахождения минимального элемента надо найти элемент в списке корней с минимальным значением (предполагается, что ключей, равных
, нет).Так как корней в этом списке не более
, то операция выполняется за .При вызове этой процедуры для кучи, изображенной на картинке ниже, будет возвращен указатель на вершину с ключем
.merge
insert
Необходимо просто создать биномиальную пирамиду
с одним узлом за время и объединяет ее с биномиальной пирамидой , содержащей узлов, за время .extractMin
Приведенная ниже процедура извлекает узел с минимальным ключом из биномиальной кучи и возвращает указатель на извлеченный узел. Процедура выполняется за время
, поскольку всего в списке корней биномиальных деревьев. И всего у найденного дерева порядка(с минимальным значением ключа) ровно детей, то сложность перебора этих детей будет тоже . То имеем асимптотику .
Node extractMin(H) { //поиск корня х с минимальным значением ключа в списке корней Н: min =; x = null; curx = H.head; while curx null { // в случае минимальности текущего ключа переприсваиваем значение текущего минимума if curx.key < min { min = curx.key; x = curx; } curx = curx.next; } //удаление найденного корня x из списка корней деревьев кучи x.prev.next = x.next; x.next.prev = x.prev; //добавление детей элемента x в кучу: H' = null; curx = x.child; while curx null { // удаление элемента x из предков curx p[curx] = null; // присвоение указателю вспомогательного дерева H' адреса текущего корня текущего ребенка H'.head = curx; // слияние нашего дерева с текущим деревом H' H = merge(H, H'); // переход к следующему ребенку curx = curx.sibling; } return x; }
Поскольку минимальный элемент находится в корневом списке, найти его легко; после его удаления соответствующее дерево рассыпается в набор биномиальных деревьев меньшего размера, который надо объединить с оставшейся частью кучи. Все действия выполняются за время
, так что общее время работы процедуры есть .decreaseKey
Следующая процедура уменьшает ключ элемента
биномиальной кучи, присваивая ему новое значение. Вершина, ключ которой был уменьшен, «всплывает» наверх. Процедура выполняется за время , поскольку глубина вершины есть (свойства биномиального дерева), а при выполнении каждого шага алгоритма мы поднимаемся вверх.
void decreaseKey(H, x, k) {
// проверка на то, что текущий ключ не меньше передаваемого ключа k
if k > key[x] then
return;
key[x] = k;
y = x;
z = p[y];
//поднимаем текущий элемент x с новым ключом k, пока
//это значение меньше значения в родительской вершине
while z
null and key[y] < key[z] do {
swap(key[y], key[z]);
y = z;
z = p[y];
}
}
Пример работы процедуры проиллюстрирован на рисунке (
— уменьшаемый элемент, — его предок).delete
Удаление ключа сводится к двум предыдущим операциям: сначала нужно уменьшить ключ до минимально возможного значения, а затем извлечь вершину с минимальным ключом. В процессе выполнения процедуры этот узел всплывает вверх, откуда и удаляется. Процедура выполняется за время
.
void delete(H, x) {
//уменшение ключа до минимально вохможного значения
decreaseKey(H, x,
);
//удаление "всплывшего" элемента
extractMin(H);
}
Источники
- Биномиальные кучи — INTUIT.ru
- Binomial heap — Wikipedia
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 538—558. — ISBN 5-8489-0857-4