Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТСД. Лекции Силантьевой / Лекция_8_11_11_деревья.doc
Скачиваний:
65
Добавлен:
10.02.2015
Размер:
342.53 Кб
Скачать

3 1 2 3

1

2

Пример2.

4

2

4

1

1

3

2

3

Выполнение программы Prg_11_2.pas

Ввод чисел 4 и 5:

ввод RR-поворот: Ввод чисел

числа 7: 2 и 1:

LL-поворот,

Ввод числа 3:

Ввод числа 6:

Пример удаления элемента из дерева:

 

Реализация алгоритма включения элемента в сбалансированное дерево:

Procedure Search(x : integer; var Q : P_tr; var H : boolean);

Var

Q1, Q2 : P_tr;

Begin

if Q = Nil then

begin

New (Q);

H := true;

with Q^ do

begin

key := x;

count := 1;

left := Nil;

right := Nil;

bal := 0;

end;

end

else

if x < Q^.key then

begin

search (x, Q^.left, H); {выросла левая ветвь}

if H then {если высота увеличилась}

case Q^.bal of

1 : begin

Q^.bal := 0;

H := false;

end;

0 : Q^.bal := -1;

-1 : begin {балансировка}

Q1 := Q^.left;

if Q1^.bal = -1 then

begin {однократный LL-поворот}

Q^.left := Q1^.right;

Q1^.right := Q;

Q^.bal := 0;

Q := Q1;

end

else

begin {двукратный LR-поворот}

Q2 := Q1^.right;

Q1^.right := Q2^.left;

Q2^.left := Q1;

Q^.left := Q2^.right;

Q2^.right := Q;

if Q2^.bal = -1 then Q^.bal := 1

else Q^.bal := 0;

if Q2^.bal = 1 then Q1^.bal := -1

else Q1^.bal := 0;

Q := Q2;

end;

Q^.bal := Q;

H := false;

end {балансировка}

end {case}

end {if x < Q^.key}

else

if x > Q^.key

begin

search (x, Q^.right, H); {выросла правая ветвь}

if H then {если высота увеличилась}

case Q^.bal of

-1 : begin

Q^.bal := 0;

H := false;

end;

0 : Q^.bal := 1;

1 : begin {балансировка}

Q1 := Q^.right;

if Q1^.bal = 1 then

begin {однократный RR-поворот}

Q^.right := Q1^.left;

Q1^.left := Q;

Q^.bal := 0;

Q := Q1;

end

else

begin {двукратный RL-поворот}

Q2 := Q1^.left;

Q1^.left := Q2^.right;

Q2^.right := Q1;

Q^.right := Q2^.left;

Q2^.left := Q;

if Q2^.bal = 1 then Q^.bal := -1

else Q^.bal := 0;

if Q2^.bal = -1 then Q1^.bal := 1;

else Q1^.bal := 0;

Q := Q2;

end;

Q^.bal := 0;

H := false;

end {балансировка}

end {case}

end {if x > Q^.key}

else

begin

Q^.count := Q^.count + 1;

end;

End; {конец процедуры}

Из-за условия балансированности высота дерева О(log(N)),

где N- количество вершин, поэтому добавление элемента требует O(log(N)) операций.

                  1. Реализация алгоритма удаления элемента из сбалансированного дерева:

основано на алгоритме удаления из дерева, то есть, замене удаляемой вершины на самого левого потомка из правого поддерева или на самого правого потомка из левого поддерева, с учетом операции балансировки (тех же поворотов узлов).

Параметр-переменнаяю Н типа Boolean показывает уменьшение высоты поддерева, то есть, Н = True, если высота уменьшилась.

Процедуры балансировки: L_Balance и R_Balance начинают работать, когда уменьшается высота левого и правого поддеревьев соответственно.

Procedure DeleteT(x : integer; var Q : P_tr; var H : boolean);

Var

P : P_Tr; {H = false}

Procedure L_Balance(var Q : P_Tr; var H : boolean);

{H = true, левая ветвь стала короче}

Var

Q1, Q2 : P_tr;

B1, B2 : -1..1;

Begin

сase Q^.bal of

-1 : Q^.bal := 0;

0 : begin

Q^.bal := 1;

H : false;

end;

1 : begin {балансировка}

Q1 := Q^.right;

B1 := Q1^.bal;

if B1 >= 0 then

begin {однократный RR-поворот}

Q^.right := Q1^.left;

Q1^.left := Q;

if B1 = 0 then

begin

Q^.bal := 1;

Q1^.bal := -1;

H := false;

end

else

begin

Q^.bal := 0;

Q1^.bal := 0;

end;

Q := Q1;

end

else

begin {двукратный RL-поворот} Q2 := Q1^.left;

B2 := Q2^.bal;

Q1^.left := Q2^.right;

Q2^.right := Q1;

Q^.right := Q2^.left;

Q2^.left := Q;

if B2 = 1 then Q1^.bal := -1

else Q1^.bal := 0;

if B2 = -1 then Q1^.bal := 1;

else Q1^.bal := 0;

Q := Q2;

Q2^.bal := 0;

end;

end; {балансировка}

end; {case}

End; {L_balance}

Procedure R_Balance(var Q : P_Tr; var H : boolean);

{H = true, правая ветвь стала короче}

Var

Q1, Q2 : P_tr;

B1, B2 : -1..1;

Begin

сase Q^.bal of

1 : Q^.bal := 0;

0 : begin

Q^.bal := -1;

H : false;

end;

-1 : begin {балансировка}

Q1 := Q^.left;

B1 := Q1^.bal;

if B1 <= 0 then

begin {однократный LL-поворот}

Q^.left := Q1^.right;

Q1^.right := Q;

if B1 = 0 then

begin

Q^.bal := -1;

Q1^.bal := 1;

H := false;

end

else

begin

Q^.bal := 0;

Q1^.bal := 0;

end;

Q := Q1;

end

else

begin {двукратный LR-поворот} Q2 := Q1^.right;

B2 := Q2^.bal;

Q1^.right := Q2^.left;

Q2^.left := Q1;

Q^.left := Q2^.right;

Q2^.right := Q;

if B2 = -1 then Q^.bal := 1

else Q^.bal := 0;

if B2 = 1 then Q1^.bal := -1;

else Q1^.bal := 0;

Q := Q2;

Q2^.bal := 0;

end;

end; {балансировка}

end; {case}

End; {R_balance}

Procedure Del (var R : P_Tr; var H : boolean);

{H = false}

Begin

if R^.right <> Nil then

begin

Del(R^.right, H);

if H then R_Balance(R, H);

end

else

begin

P^.key := R^.key;

P^.count := R^.count;

R := R^.left;

H := true;

end;

End;

Begin

if Q = Nil then

begin

writeln (‘Дерево пусто.’);

H := falsel

end

else

if x < Q^.key then

begin

DeleteT (x, Q^.left, H);

if H then L_Balance (Q, H);

end

else

if x > Q^.key then

begin

DeleteT (x, Q^.right, H);

if H then R_Balance (Q, H);

end

else

begin {удаление Q^}

P := Q;

if P^.right = Nil then

begin

Q := P^.left;

H := true;

end

else

if P^.left = Nil then

begin

Q := P^.right;

H := true;

end

else

begin

Del (Q^.left, H);

if H then L_Balance(P, H);

end;

End; {DeleteT}

Г. М. Адельсон-Вельский и Е. М. Ландис доказали теорему, согласно которой высота АВЛ-дерева с N внутренними вершинами заключена между log2(N+1) и 1.4404*log2(N+2)-0.328, то есть высота АВЛ-дерева никогда не превысит высоту идеально сбалансированного дерева более, чем на 45 %. Для больших N имеет место оценка 1.04*log2(N). Таким образом, выполнение основных операций 1 — 3 требует порядка log2(N) сравнений. Экспериментально выяснено, что одна балансировка приходится на каждые два включения и на каждые пять исключений.