52704.fb2
procedure TtdRedBlackTree.Delete(aItem : pointer);
var
Node : PtdBinTreeNode;
Dad : PtdBinTreeNode;
Child : PtdBinTreeNode;
Brother : PtdBinTreeNode;
FarNephew : PtdBinTreeNode;
NearNephew : PtdBinTreeNode;
IsBalanced : boolean;
ChildType : TtdChildType;
begin
{выполнить поиск узла, который нужно удалить; этот узел будет иметь единственный дочерний узел}
Node := bstFindNodeToDelete(aItem);
{если узел красный или является корневым, его можно безнаказанно удалить}
if (Node^.btColor = rbRed) or (Node = FBinTree.Root) then begin
FBinTree.Delete(Node);
dec(FCount);
Exit;
end;
{если единственный дочерний узел является красным, перекрасить его в черный цвет и удалить узел}
if (Node^.btChild[ctLeft] =nil) then
Child := Node^.btChild[ctRight] else
Child :=Node^.btChild[ctLeft];
if IsRed(Child) then begin
Child^.btColor :=rbBlack;
FBinTree.Delete(Node);
dec(FCount);
Exit;
end;
{на этом этапе узел, который нужно удалить, - узел Node; он является черным и известно, что дочерний узел Child, который его заменит, является черным (а также может быть нулевым!) и что существует родительский узел узла Node (который вскоре станет родительским узлом узла Child); братский узел узла Node также существует в соответствии с правилом, сформулированным для черных узлов}
{если узел Child является нулевым, необходимо несколько упростить выполнение цикла и определить родительский и братский узлы и определить, является ли узел Node левым дочерним узлом}
if (Child = nil) then begin
Dad := Node^.btParent;
if (Node = Dad^.btChild[ctLeft]) then begin
ChildType :=ctLeft;
Brother := Dad^.btChild[ctRight];
end
else begin
ChildType :=ctRight;
Brother := Dad^.btChild[ctLeft];
end;
end
else begin
{следующие три строки предназначены просто для введения в заблуждение компилятора и предотвращения вывода ряда ложных предупреждений}
Dad := nil;
Brother := nil;
ChildType :=ctLeft;
end;
{удалить узел — он больше не нужен}