Биномиальная куча — различия между версиями
Gr1n (обсуждение | вклад) |
Gr1n (обсуждение | вклад) |
||
| Строка 29: | Строка 29: | ||
*имеет корень степени <tex>k</tex>; степень всех остальных вершин меньше степени корня биномиального дерева; | *имеет корень степени <tex>k</tex>; степень всех остальных вершин меньше степени корня биномиального дерева; | ||
| − | Так как с увеличением порядка дерева мы подвешиваем к текущему корню ровно один корень другого дерева, то степень корня с увеличением порядка на 1 также увеличивается на 1. То дерево порядка <tex>k</tex> имеет корень степени <tex>k</tex>. И так как при таком увеличении порядка в полученном дереве лишь степень корня возросла, то доказываемый инвариант, то есть степень корня больше степени остальных вершин, не будет нарушаться. | + | Так как с увеличением порядка дерева мы подвешиваем к текущему корню ровно один корень другого дерева, то степень корня с увеличением порядка на <tex>1</tex> также увеличивается на <tex>1</tex>. То дерево порядка <tex>k</tex> имеет корень степени <tex>k</tex>. И так как при таком увеличении порядка в полученном дереве лишь степень корня возросла, то доказываемый инвариант, то есть степень корня больше степени остальных вершин, не будет нарушаться. |
*максимальная степень произвольного узла в биномиальном дереве с n узлами равна <tex>\log(n)</tex>. | *максимальная степень произвольного узла в биномиальном дереве с n узлами равна <tex>\log(n)</tex>. | ||
Версия 01:21, 8 марта 2012
Содержание
Биномиальное дерево
| Определение: |
| Биномиальное дерево — дерево, определяемое для каждого следующим образом: — дерево, состоящее из одного узла высоты , то есть состоит из одного узла; состоит из двух биномиальных деревьев , связанны вместе таким образом, что корень одного из них является крайним левым дочерним узлом корня второго дерева. |
Свойства биномиальных деревьев
Биномиальное дерево с n вершинами:
- имеет узлов;
Так как в дереве порядка вдвое больше узлов, чем в дереве порядка , а в дереве нулевого порядка узел, то дерево порядка имеет узлов.
- имеет высоту ;
В силу того, что с увеличением порядка дерева на , мы подвешиваем к текущему дереву дерево того же порядка, то высота получившегося в результате слияния дерева увеличивается на . Изначально имеем высоту , то при любом , дерево порядка имеет высоту .
- имеет ровно узлов на высоте ;
Докажем по индукции:
База - верно. Пусть для некоторого условие верно, то докажем, что для это также верно:
Рассмотрим уровень дерева . Дерево было получено подвешиванием одного дерева порядка к другому. Тогда на уровне дерева всего узлов , так как от подвешенного дерева в дерево порядка нам пришли узлы глубины . То для уровня дерева количество узлов . То свойство доказано.
- имеет корень степени ; степень всех остальных вершин меньше степени корня биномиального дерева;
Так как с увеличением порядка дерева мы подвешиваем к текущему корню ровно один корень другого дерева, то степень корня с увеличением порядка на также увеличивается на . То дерево порядка имеет корень степени . И так как при таком увеличении порядка в полученном дереве лишь степень корня возросла, то доказываемый инвариант, то есть степень корня больше степени остальных вершин, не будет нарушаться.
- максимальная степень произвольного узла в биномиальном дереве с n узлами равна .
Докажем это утверждение для корня. Степень остальных вершин меньше по предыдущему свойству. Так как степень корня дерева порядка равна , а узлов в этом дереве , то прологарифмировав обе части получаем, что , то степень произвольного узла не более .
Биномиальная куча
| Определение: |
Биномиальная пирамида (куча) — представляет собой множество биномиальных деревьев, которые удовлетворяют следующим свойствам :
|
Представление биномиальных куч
Поскольку количество детей у узлов варьируется в широких пределах, ссылка на детей осуществляется через левого ребенка, а остальные дети образуют односвязный список. Каждый узел в биномиальной пирамиде (куче) представляется набором полей:
- — ключ (вес) элемента;
- — указатель на родителя узла;
- — указатель на левого ребенка узла;
- — указатель на правого брата узла;
- — степень узла (количество дочерних узлов данного узла).
Корни деревьев, их которых состоит пирамида, содержатся в так называемом списке корней, при проходе по которому степени соответствующих корней находятся в неубывающем порядке. Доступ к куче осуществляется ссылкой на первый корень в списке корней.
Операции над биномиальными кучами
Рассмотрим операции, которые можно производить с биномиальной пирамидой. Их асимптотические оценки показаны в таблице.
| insert | |
| getMinimum | |
| extractMin | |
| merge | |
| decreaseKey | |
| delete |
Обозначим нашу кучу за . То пусть — указатель на корень биномиального дерева минимального порядка этой кучи. Изначально , то есть пирамида не содержит элементов.
getMinimum
Для нахождения минимального элемента надо найти элемент в списке корней с минимальным значением (предполагается, что ключей, равных , нет).
Асимптотика этой операции получается из того, что корней в этом списке не более .
При вызове этой процедуры для кучи, изображенной на картинке ниже, будет возвращен указатель на вершину с ключем .
merge
Эта операция, соединяющая две биномиальные кучи в одну, используется в качестве подпрограммы большинством остальных операций.
Для этого нам надо сначала слить списки корней в единый связный список, отсортированный по степеням в монотонно возрастающем порядке. Для каждого элемента списка известна ссылка на следующего и предыдущего корня. Свойство пирамиды обеспечивает нам в новом списке наличие не более двух деревьев одинаковой степени. Далее мы за один проход по этому списку объединим некоторые деревья так, что в результате все они будут иметь попарно разные степени. Рассмотрим подробнее процесс прохождения по этому списку:
Если текущий корень имеет разные степени с следующим за ним, то ничего с ним не делаем и продолжаем цикл. Это дерево в итоге останется в таком виде в конечной куче(случай на рисунке). Если же степень текущего элемента равна степеням последующих двух вершин(это может случится в том случае, если в каждом из двух исходных деревьев был корень с этой степенью и еще одно дерево образовалось в ходе текущего слияния деревьев; причем более, чем трех корней с одинаковой степенью быть не может по нашему алгоритму и начальным условиям), то оставим это дерево нетронутым, но после на следующем шаге сольем два других дерева с этой степенью. Иными словами переходим к следующей вершине, в которой уже будет происходить слияние(случай на рисунке). В последнем случае мы имеем лишь две подряд вершины с одинаковой степенью корней. В этой ситуаций мы дерево с большим значением в корне вершины подвешиваем к дерево с меньшим значением в корне (случаи на рисунке).
Прим. на рисунке — следующий элемент в списке для
Пример пирамиды до merge и после:
insert
Необходимо просто создать биномиальную пирамиду с одним узлом за время и объединяет ее с биномиальной пирамидой , содержащей узлов, за время .
extractMin
Приведенная ниже процедура извлекает узел с минимальным ключом из биномиальной кучи и возвращает указатель на извлеченный узел. Процедура выполняется за время , поскольку всего в списке корней биномиальных деревьев. И всего у найденного дерева порядка(с минимальным значением ключа) ровно детей, то сложность перебора этих детей будет тоже . То общая асимптотика .
Node extractMin(H) {
//поиск корня х с минимальным значением ключа в списке корней Н
min = ;
x = null;
curx = head[H];
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 {
p[curx] = null; // удаление элемента x из предков curx
head[H'] = curx;
H = merge(H, H'); // слияние нашего дерева с текущим деревом H'
curx = curx.sibling;
}
return x;
}
Поскольку минимальный элемент находится в корневом списке, найти его легко; после его удаления соответствующее дерево рассыпается в набор биномиальных деревьев меньшего размера, который надо объединить с оставшейся частью кучи. Все действия выполняются за время , так что общее время работы процедуры есть .
decreaseKey
Следующая процедура уменьшает ключ элемента биномиальной кучи, присваивая ему новое значение. Вершина, ключ которой был уменьшен, «всплывает» наверх. Процедура выполняется за время , поскольку глубина вершины есть (свойства биномиального дерева), а при выполнении каждого шага алгоритма мы поднимаемся вверх.
void decreaseKey(H, x, 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

