52704.fb2 Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 147

Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 147

NearNephew^.btColor := Dad^.btColor;

Dad^.btColor :=rbBlack;

rbtPromote(rbtPromote(NearNephew));

end

{в противном случае ближний узел-племянник является также черным}

else begin

{если родительский узел красный, окрасить его в черный цвет, а братский узел в красный, в результате чего задача будет выполнена}

if (Dad^.btColor = rbRed) then begin

Dad^.btColor :=rbBlack;

Brother^.btColor := rbRed;

end

{в противном случае родительский узел красный: окрасить братский узел в красный цвет и начать балансировку с родительского узла}

else begin

Brother^.btColor := rbRed;

Node := Dad;

IsBalanced := false;

end;

end;

end;

end;

end;

until IsBalanced;

end;

За исключением перекрытых методов Insert и Delete, класс TtdRedBlackTree не представляет особого интереса. Код интерфейса и дополнительного внутреннего метода, выполняющего повышение ранга узла, приведен в листинге 8.26.

Листинг 8.26. Класс TtdRedBlack и метод повышения ранга узла

type

TtdRedBlackTree = class(TtdBinarySearchTree) private protected

function rbtPromote(aNode : PtdBinTreeNode): PtdBinTreeNode;

public

procedure Delete(aItem : pointer); override;

procedure Insert(aItem : pointer); override;

end;

function TtdRedBlackTree.rbtPromote(aNode : PtdBinTreeNode): PtdBinTreeNode;

var

Parent : PtdBinTreeNode;

begin

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

Parent := aNode^.btParent;

{в обоих случаях существует 6 связей, которые необходимо разорвать и перестроить: связь узла с его дочерним узлом и противоположная связь; связь узла с его родительским узлом и противоположная связь; и связь родительского узла с его родительским узлом и противоположная связь; обратите внимание, что дочерний узел данного узла может быть нулевым}

{повысить ранг левого дочернего узла, т.е. выполнить поворот родительского узла вправо}

if (Parent^.btChild[ctLeft] = aNode) then begin

Parent^.btChild[ctLeft] := aNode^.btChild[ctRight];

if (Parent^.btChild[ctLeft]<> nil) then

Parent^.btChild[ctLeft]^.btParent := Parent;

aNode^.btParent := Parent^.btParent;

if (aNode^.btParent^.btChild[ctLeft] = Parent) then

aNode^.btParent^.btChild[ctLeft] := anode

else

aNode^.btParent^.btChild[ctRight J := aNode;

aNode^.btChild[ctRight] := Parent;