АЛГОРИТМ ПРОЦЕДУРЫ Balance_R.


Дано: бинарное дерево, в левом поддереве которого было произведено удаление элемента.

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

_Начало . Balance_R:

1. Корректировка показателей сбалансированности:

_Если . BAL(p)=1

_то .: BAL(p)=0; { перевеш. -> сбалансированная. }

_конец

_Если . BAL(p)=0

_то .: BAL(p)=-1; h=false; { сбалансир. -> перевешивающая. }

_конец

p1=LPTR(p); b1=BAL(p1); { BAL(p)=1 - критическая. }

2. Однократный LL-поворот :

_если . b1 <= 0

_то .:

_если . p=ROOT _то . ROOT=LPTR(p); { перенос корня }

LPTR(p)=RPTR(p1); RPTR(P1)=p;

{ корректировка показателей сбалансированности }

_если . b1=0

_то .: BAL(p)=-1; BAL(p1)=1; h=false;

_иначе .: BAL(p)=0; BAL(p1)=0;

p=p1;

_конец

3. Двукратный RL-поворот :

_если . b1 > 0

_если . p1=ROOT _то . ROOT=LPTR(p); { перенос корня }

p2=RPTR(p1); b2=BAL(p2);

RPTR(p1)=LPTR(p2); LPTR(p2)=p1;

LPTR(p)=RPTR(p2); RPTR(p2)=p;

{ корректировка показателей сбалансированности }

_если . b2=-1 _то . BAL(p)=1 _иначе . BAL(p)=0;

_если . b2=1 _то . BAL(p1)=-1 _иначе . BAL(p1)=0;

p=p2; BAL(p2)=0;

_конец

_Конец . Balance_R;

Метод работы аналогичен алгоритму Balance_L.

ТЕКСТЫ ПРОЦЕДУР Delete 1, 0 Del 1, 0Balance_L и Balance_R.

Так как процедуры Del, Balance_L и Balance_R используются только процедурой Delete, то их можно выполнить вложенными в Delete.

{=====Программный пример 6.20 ========}

Procedure Delete (x:integer; var p,root:ref; var h:boolean);

var q:ref; {h:false}

procedure Balance_L ( var p:ref; var h:boolean);

{уменьшается высота левого поддерева}

var p1,p2:ref;

b1,b2:-1..+1;

begin { h-true, левая ветвь стала короче }

case p^.BAL of

-1: p^.BAL:=0;

0: begin p^.BAL:=+1; h:=false; end;

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

p1:=p^.right; b1:=p1^.BAL;

if b1 >= 0 then begin { однократный RR-поворот }

if p=root then root:=p^.right; p^.right:=p1^.left;

p1^.left:=p;

if b1 = 0 then begin

p^.BAL:=+1; p1^.BAL:=-1; h:=false; end

else begin p^.BAL:=0; p1^.BAL:=0; end;

p:=p1;

end

else begin { 2-кратный RL-поворот }

if p1=root then root:=p1^.right; p2:=p1^.left;

b2:=p2^.BAL; p1^.left:=p2^.right; p2^.right:=p1;

p^.right:=p2^.left; p2^.left:=p;

if b2=+1 then p^.BAL:=-1 else p^.BAL:=0;

if b2=-1 then p1^.BAL:=+1 else p1^.BAL:=0;

p:=p2; p2^.BAL:=0; end;

end; { begin 3 }

end; { case }

end; {Balance_L}

procedure Balance_R (var p:ref; var h:boolean);

{ уменьшается высота правого поддерева }

var p1,p2:ref;

b1,b2:-1..+1;

begin { h-true, правая ветвь стала короче }

case p^.BAL of

1: p^.BAL:=0;

0: begin p^.BAL:=-1; h:=false; end;

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

p1:=p^.left; b1:=p1^.BAL;

if b1 <= 0 then begin { однократный LL-поворот }

if p=root then root:=p^.left;

p^.left:=p1^.right; p1^.right:=p;

if b1 = 0

then begin p^.BAL:=-1; p1^.BAL:=+1; h:=false; end

else begin p^.BAL:=0; p1^.BAL:=0; end;

p:=p1;

end

else begin { 2-кратный LR-поворот }

if p1=root then root:=p1^.left;

p2:=p1^.right; b2:=p2^.BAL;

p1^.right:=p2^.left; p2^.left:=p1;

p^.left:=p2^.right; p2^.right:=p;

if b2=-1 then p^.BAL:=+1 else p^.BAL:=0;

if b2=+1 then p1^.BAL:=-1 else p1^.BAL:=0;

p:=p2; p2^.BAL:=0;

end; end; end;

end; {Balance_R}

Procedure Del (var r:ref; var h:boolean);

begin { h-false }

if r^.right <> nil then

begin Del(r^.right,h);

if h then Balance_R(r,h);

end else begin q^.key:=r^.key; r:=r^.left; _ .h:=true; end;

end;{Del}

Begin {Delete}

if p=nil

then begin TextColor(white); GotoXY(а,b+2);

write ('Ключа в дереве нет'); h:=false; end

else if x < p^.key

then begin Delete(x,p^.left,root,h);

if h then Balance_L(p,h); end

else if x > p^.key then

begin Delete(x,p^.right,root,h);

if h then Balance_R(p,h); end

else begin { удаление p^ }

q:=p; if q^.right=nil

then begin p:=q^.left; h:=true; end

else if q^.left=nil then

begin p:=q^.right; h:=true; end

else begin Del(q^.left,h);

if h then Balance_L(p,h);

end;

GotoXY(а,b);

writeln(' Узел с ключом ',x,' удален из дерева.');

end;

End{Delete};

ПОИСК ЭЛЕМЕНТА.

Поиск элемента в сбалансированном дереве уже применялся в операциях вставки и удаления элементов. Поэтому необходимо отдельно рассмотреть эту операцию.

Пусть дано некоторое бинарное дерево, в котором каждый левый элемент меньше вышележащего, а правый - больше.

Для нахождения элемента с заданным ключом начинаем поиск с корневого элемента, сравнивая его ключ с искомым. Если искомый ключ меньше, то продолжаем поиск по левому поддереву (так как его элемент меньше текущего), а если ключ больше - то по правому (его элемент больше). Сравнивая аналогичным образом искомый ключ с ключом текущего элемента мы будем последовательно спускаться по дереву до тех пор, пока ключи искомого и текущего элемента не совпадут - элемент найден. Если мы дошли до уровня листьев (ниже элементов уже нет), а элемент не найден, значит он отсутствует в дереве.

Этот алгоритм пригоден для поиска в любых бинарных деревьях, но при работе со сбалансированными деревьями время поиска элемента минимально.

АЛГОРИТМ Search.

Дано: ключ - X.

Алгоритм производит рекурсивный обход сбалансированного дерева и находит элемент с заданным ключом, либо сообщает об отсутствии такого элемента.

1. Поиск элемента:

_Если . x < key(p)

_то .: _если . p=nil

_то .: напечатать "Элемент отсутствует" и _конец ..

_иначе .: p=LPTR(p) и вызвать процедуру Search;

_Если . x > key(p)

_то .: _если . p=nil

_то .: напечатать "Элемент отсутствует" и _конец ..

_иначе .: p=RPTR(p) и вызвать процедуру Search;

2. Совпадение:

Напечатать "Элемент найден";

Произвести операции обработки элемента и _конец ..



Дата добавления: 2016-07-22; просмотров: 1524;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.013 сек.