Графы. Модели вычислений. Структуры данных
..pdfРис. 3
Следующий по направлению к корню узел правой ветви имеет ключ 8, ранг его левого сына не меньше ранга правого сына, следовательно, условие левизны выполняется и поэтому транспонирования его левого и правого поддеревьев не требуется. Однако ранг этого узла необходимо обновить, так как его старое значение 1 не совпадает с увеличенным на 1 минимальным из рангов его потомков, то есть с числом 2. Обновив ранг, получим кучу, изображенную на рис. 4.
(2)3
|
2 |
10 |
|
|
|
|
(3) |
6 |
|
|
|
|
|
1 |
21 |
1 |
14 |
|
2 |
12 |
|
|
(2) |
7 |
|
|
|
|
1 |
23 |
|
1 |
18 |
|
1 |
24 |
1 |
37 |
2 |
8 |
|
|
|
|
|
|
1 |
33 |
|
|
|
1 |
17 |
1 |
18 |
|
|
|
|
|
|
|
|
|
1 |
26 |
|
|
|
Рис. 4
Теперь рассмотрим узел с ключом 7. Он имеет левого сына с ключом 37 и рангом 1 и правого сына с ключом 8 и рангом 2. Для восстановления свойства левизны в этом узле необходимо поменять местами его левое и правое поддеревья и обновить ранг. Его новым значением будет минимум
241
из рангов его потомков (это ранг нового правого сына) плюс 1, то есть 2.
Врезультате получаем дерево, изображенное на рис. 5.
(2)3
|
2 |
10 |
|
|
|
|
(3) |
6 |
|
|
|
|
1 |
21 |
1 |
14 |
|
2 |
12 |
|
|
|
2 |
7 |
|
|
1 |
23 |
|
1 |
18 |
|
1 |
24 |
2 |
8 |
1 |
37 |
|
|
|
|
|
1 |
33 |
|
1 |
17 |
1 |
18 |
|
1 26
Рис. 5
Далее рассматриваем узел с ключом 6. Оба его сына имеют одинаковый ранг 2, следовательно, менять их местами не требуется. Вычислим лишь новое значение ранга: оно равно минимальному из рангов его детей (рангу правого сына) плюс 1, то есть 3. Получаем дерево, изображенное на рис. 6.
(2)3
|
2 |
10 |
|
|
|
|
|
3 |
6 |
|
|
|
1 |
21 |
1 |
14 |
|
2 |
12 |
|
|
|
2 |
7 |
|
|
1 |
23 |
|
1 |
18 |
|
1 |
24 |
2 |
8 |
1 |
37 |
|
|
|
|
|
1 |
33 |
|
1 |
17 |
1 |
18 |
|
1 26
Рис. 6
Наконец, рассматриваем узел с ключом 3, который является последним в правой ветви, полученной слиянием правых ветвей исходных куч. Его потомков (узлы с ключами 10 и 6) необходимо поменять местами для
242
восстановления свойства левизны и обновить ранг, который будет теперь равен 3. После выполнения этих операций получим левостороннюю кучу, изображенную на рис. 7. На этом выполнение операции СЛИЯНИЕ заканчивается.
|
|
|
|
|
|
|
3 |
3 |
|
|
|
|
|
|
3 |
6 |
|
|
|
|
|
10 |
|
|
2 |
12 |
|
|
|
2 |
7 |
1 |
21 |
1 |
14 |
1 |
18 |
1 |
24 |
|
2 |
8 |
|
37 |
1 |
23 |
|
|
1 |
33 |
1 |
17 |
|
|
1 18 |
|
|
|
|
1 26
Рис. 7
Очевидно, время выполнения операции СЛИЯНИЕ пропорционально сумме длин правых путей сливаемых куч. По свойству левосторонней кучи оно не превосходит величины log n1 + log n2 < log n + log n, где n1, n2 – количества узлов в исходных кучах, а n = n1 + n2 – количество узлов в результирующей куче. Следовательно, вычислительная сложность операции СЛИЯНИЕ равна O(log n).
Реализация операции СЛИЯНИЕ
procedure СЛИЯНИЕ(h1, h2, h); begin
if h1 = nil then {h := h2; exit}; if h2 = nil then {h := h1; exit};
if h1^.key > h2^.key then {h3 := h1; h1 := h2; h2 := h3;} h := h1; СЛИЯНИЕ(h1^. right, h2, h3); h^. right := h3; if h^.left^.rank < h^.right^.rank then
{h3:= h^.left; h^.left := h^.right; h^.right := h3}; h^.rank := min(h^.right^.rank, h^.left^.rank) + 1;
end;
Операция ВСТАВКА. Эта операция позволяет осуществить вставку в кучу h нового элемента x с ключом k. Она производится посредством об-
243
разования левосторонней кучи, содержащей единственный элемент х с ключом k, и слияния ее с кучей h. Вычислительную сложность данной операции можно оценить так же, как вычислительную сложность операции СЛИЯНИЕ, то есть величиной O (log n).
Реализация операции ВСТАВКА
procedure ВСТАВКА(x, k, h); begin
CREATE node h1: [element, key, rank, left, right, parent] = [x, k, 1, nil, nil, nil];
СЛИЯНИЕ(h, h1, h2); h := h2 end;
Операция УДАЛЕНИЕ_МИНИМУМА. Эта операция позволяет из кучи h удалить элемент хMin с минимальным ключом. Она производится посредством удаления корня кучи h (трудоемкость O (1)), а затем слияния его левой и правой подкуч (трудоемкость O (log n)). Таким образом, вычислительная сложность данной операции является величиной O (log n).
Реализация операции УДАЛЕНИЕ_МИНИНИМУМА
procedure УДАЛЕНИЕ_МИНИМУМА (h, xMin); begin
xMin := h^.element; СЛИЯНИЕ (h^.left, h^.right, h3); h := h3 end;
Операция МИНИМУМ. Эта операция позволяет взять из кучи h элемент с минимальным ключом, не удаляя его из кучи. Поскольку элемент с минимальным ключом находится в корне кучи, то требуется лишь скопировать его в нужное место. Вычислительная сложность данной операции
O (1).
Реализация операции МИНИМУМ
function МИНИМУМ (h); begin
МИНИМУМ := h^.element; end;
Операция УДАЛЕНИЕ. Эта операция позволяет удалить из кучи h элемент х, расположенный в узле, заданном позицией pos. Удаление может быть проведено в несколько этапов.
1. Если узел х является корнем кучи h, то применяется операция
244
УДАЛЕНИЕ_МИНИМУМА из кучи h. Иначе выполняются следующие действия.
2.От исходной кучи h отрывается подкуча h2 с корнем в удаляемом узле х. Оставшаяся куча, для которой сохраняем обозначение h, не обязательно является левосторонней.
3.Затем узел х удаляется из кучи h2, а его левая и правая подкучи сли-
ваются в одну кучу h2′ (время выполнения – O (log n), как доказано выше).
4. Куча h2′ делается таким же сыном узла р (р – родитель узла х), ка-
ким являлся для нее узел х (левым или правым).
5. Наконец, в куче h восстанавливается свойство левизны. Фактически свойству левизны могут не удовлетворять только узлы, находящиеся на пути от р к корню кучи h. Длина этого пути в худшем случае может линейно зависеть от n. Но на самом деле нам нужно проверить только первые не более чем log (n + 1) узлов на этом пути (потому что максимальный по длине правый путь имеет максимум log (n + 1) узлов).
Таким образом, время выполнения данной операции – O (log n). Рассмотрим пример выполнения данной операции. Пусть из кучи h,
изображенной на рис. 8, необходимо удалить элемент х с ключом 9.
|
|
|
|
|
|
h:3 |
2 |
|
|
|
|
|
|
3 |
4 |
|
|
|
2 |
11 |
|
|
|
p: |
|
|
|
|
|
|
|
|
|
2 |
9 |
|
|
2 |
5 |
1 |
12 |
1 |
17 |
|
x: |
|
|
|
|
|
|
|
|
|
1 |
18 |
1 |
10 |
1 |
8 |
1 |
6 |
1 |
18 |
|
1 31 |
|
|
1 |
15 |
|
1 11 |
|
|
|
|
|
|
|
|
1 |
21 |
|
|
|
|
|
|
|
|
|
|
Рис. 8 |
|
|
|
|
Сначала отрывается подкуча h2 с корнем х. От h остаются куча h1 (нелевосторонняя, так как свойству левизны не удовлетворяет узел р) и левосторонняя куча h2, см. рис. 9.
245
|
|
|
|
|
|
h1:3 |
2 |
|
|
|
|
|
|
|
3 |
4 |
|
|
|
|
2 |
11 |
|
|
h2: |
p: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
9 |
|
|
2 |
5 |
|
1 |
12 |
1 |
17 |
|
x: |
|
|
|
|
|
|
|
|
|
|
1 |
18 |
1 |
10 |
1 |
8 |
1 |
6 |
|
1 |
18 |
|
1 31 |
|
|
1 |
15 |
|
1 11 |
|
|
|
|
|
|
|
|
|
1 |
21 |
|
|
|
|
|
|
Рис. 9
Затем удаляется узел х, а его левая и правая подкучи h2L и h2R сливаются в одну кучу h2′ при помощи вышеописанной операции СЛИЯНИЕ; см. рис. 10.
|
h2L |
h2R: |
|
1 |
h′2: |
1 |
18 |
|
|
10 |
|
|
1 10 |
1 |
|
|
|
1 31 |
|
18 |
|
||
|
1 |
31 |
|
|
|
|
|
|
|
Рис. 10
Поскольку узел х не являлся корнем кучи h, операция еще не завершена. Куча h2′ становится левым поддеревом узла р, так как узел х был его левым сыном, см. рис. 11.
|
|
|
(3) |
|
|
h:(3) |
2 |
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
||
|
|
|
p: |
4 |
|
|
|
|
2 |
|
|
|
|
1 |
10 |
|
|
2 |
5 |
1 |
12 |
1 |
17 |
|
1 |
18 |
|
|
1 |
8 |
1 |
6 |
1 |
18 |
|
1 |
31 |
|
|
1 |
15 |
1 |
1 11 |
|
|
|
|
Следуем от узла |
|
|
21 |
|
|
|
|
||||
р к корню дерева, для каждого узла этого пути вос- |
|||||||||||
|
|
|
|
|
|
|
|
Рис. 11 |
|
|
246
станавливаем свойство левизны и ранг. Сначала проверяем узел р: его детей надо поменять местами, так как ранг узла с ключом 10 (он равен 1) меньше ранга узла с ключом 5 (он равен 2). После этого обновляется ранг узла р: он равен рангу правого сына плюс 1, то есть 2. Получилось дерево, изображенное на рис. 12.
|
|
|
|
|
|
h:(3) |
2 |
|
|
|
|
|
|
|
2 |
4 |
|
|
|
|
2 |
11 |
|
|
2 |
5 |
|
|
|
1 |
1 |
1 |
12 |
1 |
17 |
1 |
8 |
1 |
6 |
|
1 |
1 |
|
|
1 |
18 |
|
1 15 |
|
1 11 |
|
1 |
31 |
|
|
|
|
|
|
1 21
Рис. 12
Следующий узел на пути к корню – это родитель узла р с ключом равным 2. Ранги его сыновей равны, значит менять их местами не нужно. Однако его собственный ранг возможно требует обновления, новое значение равно рангу его правого сына плюс 1, т.е. старому: 3. В результате получается дерево, изображенное на рис. 13.
|
|
|
|
|
|
h: |
3 |
2 |
|
|
|
|
|
|
2 |
4 |
|
|
|
|
2 |
11 |
|
|
2 |
5 |
|
|
|
1 |
1 |
1 |
12 |
1 |
17 |
1 |
8 |
1 |
6 |
|
1 |
1 |
|
|
1 |
18 |
|
1 15 |
|
1 11 |
|
1 |
31 |
|
|
|
|
|
|
1 21
Рис. 13
Поскольку узел с ключом 2 является корнем дерева, операция
247
УДАЛЕНИЕ завершена.
Реализация операции УДАЛЕНИЕ
procedure УДАЛЕНИЕ (h, pos); begin
if pos = h then {УДАЛЕНИЕ_МИНИМУМА (h, xMin); exit};
p := pos^.parent; h2 := pos; УДАЛЕНИЕ_МИНИМУМА (h2, xMin); if p^.left = pos then p^.left := h2 else p^.right := h2;
while p ≠ nil do begin
if p^.left ≠ nil then r1:= p^.left^.rank else r1:= 0; if p^.right ≠ nil then r2:= p^.right^.rank else r2:= 0; newrank := min (r1, r2) + 1;
if r1 < r2 then tr (p^.left, p^.right);
if newrank ≠ p^.parent^.rank then p^.parent^.rank:= newrank else exit;
p:= p^.parent; end
end
Операция УМЕНЬШИТЬ_КЛЮЧ. Ключ узла x, находящегося в дереве в позиции pos, уменьшается на положительное число ∆. Это действие может нарушить кучеобразный порядок лишь таким образом, что уменьшенный ключ узла х будет меньше ключа его родителя. Уменьшение ключа может быть проведено в несколько этапов:
1.От исходной кучи h отрывается подкуча h2 с корнем в узле х. Оставшаяся куча h не обязательно будет левосторонней.
2.Затем ключ узла х уменьшается на заданное число ∆. Куча h2 при этом все еще остается левосторонней.
3.В куче h следующим образом восстанавливается свойство левизны. Фактически свойству левизны могут не удовлетворять только узлы, нахо-
дящиеся на пути от р (р – родитель узла х) до корня h. Длина этого пути в худшем случае линейно зависит от n. Но на самом деле нам нужно проверить только первые не более чем log (n + 1) узлов на этом пути.
Наконец, куча h сливается с h2 за время O (log n).
Таким образом, время выполнения данной операции – O (log n). Рассмотрим пример выполнения рассматриваемой операции. Пусть
в куче, изображенной на рис. 14, необходимо уменьшить ключ узла х от
248
9 до 0.
|
|
|
|
|
|
h: |
3 |
2 |
|
|
|
p: |
|
3 |
4 |
|
|
|
|
2 |
11 |
x: |
2 9 |
|
|
|
|
2 |
5 |
|
1 12 |
1 17 |
1 |
18 |
1 |
10 |
|
1 |
8 |
1 |
6 |
1 |
18 |
|
1 11 |
|||||||||
1 31 |
|
|
|
1 |
15 |
|
|
|
1 21
Рис. 14
Делается это следующим образом. От исходной кучи h отрывается подкуча h2 с корнем в удаляемом узле х. Теперь куча h не является левосторонней, так как в узле р нарушено свойство левизны; см. рис. 15.
|
|
|
|
|
|
|
h: |
(3) |
2 |
|
|
|
|
|
p: |
(3) |
4 |
|
|
|
|
2 |
11 |
|
h2: |
2 |
9 |
|
|
|
2 |
5 |
|
1 12 |
1 17 |
|
|
x: |
|
|
|
|
|
1 |
6 |
|
|
|
1 |
18 |
1 |
10 |
|
1 |
8 |
1 |
18 |
||
|
|
1 11 |
|||||||||
1 |
31 |
|
|
|
1 |
15 |
|
|
|
1 21
Рис. 15
Ключ узла х уменьшается до 0, куча h2 при этом все еще остается левосторонней; см. рис. 16.
x: 2 0
1 |
18 |
1 |
10 |
1 31
Рис. 16
Следуем от узла р до корня дерева h, для каждого узла этого пути вос-
249
станавливаем свойство левизны и ранг. Сначала проверяем узел р: его детей надо поменять местами (а фактически – только одного-единственного правого сына сделать левым). После этого вычисляется новый ранг узла р: он равен рангу правого сына плюс 1, то есть 1 (так как правого сына нет). Получилось дерево, изображенное на рис. 17.
|
|
|
|
h: (3 |
2 |
|
|
|
|
|
|
p: |
1 4 |
|
2 |
11 |
|
|
2 |
|
5 |
|
1 |
12 |
1 |
17 |
1 |
8 |
|
1 |
6 |
|
1 |
18 |
|
1 15 |
|
1 |
11 |
|
|
|
|
|
1 21
Рис. 17
Следующий узел – это родитель узла р с ключом 2. Его потомков тоже необходимо поменять местами (так как ранг левого сына меньше ранга правого). После этого ранг узла с ключом 2 вычисляется как ранг правого сына плюс 1, то есть 2. Получается куча, представленная на рис. 18:
|
|
|
h: |
2 2 |
|
|
|
|
|
|
2 |
11 |
|
|
|
|
|
1 |
4 |
1 |
12 |
1 |
17 |
|
2 |
|
5 |
|
|
|
1 |
18 |
|
1 |
8 |
|
1 |
6 |
|
|
|
|
|
1 15 |
|
1 |
11 |
|
|
1 21
Рис. 18
Наконец, сливаем кучи h и h2, получая в результате левостороннюю кучу (см. рис. 19).
|
|
|
|
|
|
|
h: |
2 |
0 |
|
|
|
250 |
|
|
|
3 |
2 |
|
|
|
|
|
1 |
18 |
|
2 |
11 |
|
|
|
2 |
4 |
|
1 |
31 |
|
|
1 |
12 |
|
1 |
17 |
2 |
5 |
|
1 |
10 |
|
|
|
|
|
1 |
18 |
|
1 |
8 |
|
1 |
6 |
|
|
|
|
|
|
|
1 |
15 |
|
1 11 |
|
|
|
|
|
|
|
|
|
|
|
1 |
21 |
|
|
|
|
|