avglvltree: replaced recursion with simple loop

git-svn-id: trunk@36134 -
This commit is contained in:
mattias 2012-03-17 19:12:19 +00:00
parent c41894692e
commit ef5ef38048

View File

@ -830,135 +830,134 @@ var
OldRightLeftLeft, OldRightLeftRight, OldLeftRightLeft, OldLeftRightRight OldRightLeftLeft, OldRightLeftRight, OldLeftRightLeft, OldLeftRightRight
: TAvgLvlTreeNode; : TAvgLvlTreeNode;
begin begin
if (ANode=nil) then exit; while ANode<>nil do begin
if ((ANode.Balance=+1) or (ANode.Balance=-1)) then exit; if ((ANode.Balance=+1) or (ANode.Balance=-1)) then exit;
OldParent:=ANode.Parent; OldParent:=ANode.Parent;
if (ANode.Balance=0) then begin if (ANode.Balance=0) then begin
// Treeheight has decreased by one // Treeheight has decreased by one
if (OldParent<>nil) then begin if (OldParent=nil) then
exit;
if(OldParent.Left=ANode) then if(OldParent.Left=ANode) then
Inc(OldParent.Balance) Inc(OldParent.Balance)
else else
Dec(OldParent.Balance); Dec(OldParent.Balance);
BalanceAfterDelete(OldParent); ANode:=OldParent;
end; end else if (ANode.Balance=+2) then begin
exit; // Node is overweighted to the right
end; OldRight:=ANode.Right;
if (ANode.Balance=+2) then begin if (OldRight.Balance>=0) then begin
// Node is overweighted to the right // OldRight.Balance is 0 or -1
OldRight:=ANode.Right; // rotate left
if (OldRight.Balance>=0) then begin OldRightLeft:=OldRight.Left;
// OldRight.Balance is 0 or -1 if (OldParent<>nil) then begin
// rotate left if (OldParent.Left=ANode) then
OldRightLeft:=OldRight.Left; OldParent.Left:=OldRight
if (OldParent<>nil) then begin else
if (OldParent.Left=ANode) then OldParent.Right:=OldRight;
OldParent.Left:=OldRight end else
fRoot:=OldRight;
ANode.Parent:=OldRight;
ANode.Right:=OldRightLeft;
OldRight.Parent:=OldParent;
OldRight.Left:=ANode;
if (OldRightLeft<>nil) then
OldRightLeft.Parent:=ANode;
ANode.Balance:=(1-OldRight.Balance); // toggle 0 and 1
Dec(OldRight.Balance);
ANode:=OldRight;
end else begin
// OldRight.Balance=-1
// double rotate right left
OldRightLeft:=OldRight.Left;
OldRightLeftLeft:=OldRightLeft.Left;
OldRightLeftRight:=OldRightLeft.Right;
if (OldParent<>nil) then begin
if (OldParent.Left=ANode) then
OldParent.Left:=OldRightLeft
else
OldParent.Right:=OldRightLeft;
end else
fRoot:=OldRightLeft;
ANode.Parent:=OldRightLeft;
ANode.Right:=OldRightLeftLeft;
OldRight.Parent:=OldRightLeft;
OldRight.Left:=OldRightLeftRight;
OldRightLeft.Parent:=OldParent;
OldRightLeft.Left:=ANode;
OldRightLeft.Right:=OldRight;
if (OldRightLeftLeft<>nil) then
OldRightLeftLeft.Parent:=ANode;
if (OldRightLeftRight<>nil) then
OldRightLeftRight.Parent:=OldRight;
if (OldRightLeft.Balance<=0) then
ANode.Balance:=0
else else
OldParent.Right:=OldRight; ANode.Balance:=-1;
end else if (OldRightLeft.Balance>=0) then
fRoot:=OldRight; OldRight.Balance:=0
ANode.Parent:=OldRight; else
ANode.Right:=OldRightLeft; OldRight.Balance:=+1;
OldRight.Parent:=OldParent; OldRightLeft.Balance:=0;
OldRight.Left:=ANode; ANode:=OldRightLeft;
if (OldRightLeft<>nil) then end;
OldRightLeft.Parent:=ANode;
ANode.Balance:=(1-OldRight.Balance); // toggle 0 and 1
Dec(OldRight.Balance);
BalanceAfterDelete(OldRight);
end else begin end else begin
// OldRight.Balance=-1 // Node.Balance=-2
// double rotate right left // Node is overweighted to the left
OldRightLeft:=OldRight.Left; OldLeft:=ANode.Left;
OldRightLeftLeft:=OldRightLeft.Left; if (OldLeft.Balance<=0) then begin
OldRightLeftRight:=OldRightLeft.Right; // rotate right
if (OldParent<>nil) then begin OldLeftRight:=OldLeft.Right;
if (OldParent.Left=ANode) then if (OldParent<>nil) then begin
OldParent.Left:=OldRightLeft if (OldParent.Left=ANode) then
OldParent.Left:=OldLeft
else
OldParent.Right:=OldLeft;
end else
fRoot:=OldLeft;
ANode.Parent:=OldLeft;
ANode.Left:=OldLeftRight;
OldLeft.Parent:=OldParent;
OldLeft.Right:=ANode;
if (OldLeftRight<>nil) then
OldLeftRight.Parent:=ANode;
ANode.Balance:=(-1-OldLeft.Balance); // toggle 0 and -1
Inc(OldLeft.Balance);
ANode:=OldLeft;
end else begin
// OldLeft.Balance = 1
// double rotate left right
OldLeftRight:=OldLeft.Right;
OldLeftRightLeft:=OldLeftRight.Left;
OldLeftRightRight:=OldLeftRight.Right;
if (OldParent<>nil) then begin
if (OldParent.Left=ANode) then
OldParent.Left:=OldLeftRight
else
OldParent.Right:=OldLeftRight;
end else
fRoot:=OldLeftRight;
ANode.Parent:=OldLeftRight;
ANode.Left:=OldLeftRightRight;
OldLeft.Parent:=OldLeftRight;
OldLeft.Right:=OldLeftRightLeft;
OldLeftRight.Parent:=OldParent;
OldLeftRight.Left:=OldLeft;
OldLeftRight.Right:=ANode;
if (OldLeftRightLeft<>nil) then
OldLeftRightLeft.Parent:=OldLeft;
if (OldLeftRightRight<>nil) then
OldLeftRightRight.Parent:=ANode;
if (OldLeftRight.Balance>=0) then
ANode.Balance:=0
else else
OldParent.Right:=OldRightLeft; ANode.Balance:=+1;
end else if (OldLeftRight.Balance<=0) then
fRoot:=OldRightLeft; OldLeft.Balance:=0
ANode.Parent:=OldRightLeft;
ANode.Right:=OldRightLeftLeft;
OldRight.Parent:=OldRightLeft;
OldRight.Left:=OldRightLeftRight;
OldRightLeft.Parent:=OldParent;
OldRightLeft.Left:=ANode;
OldRightLeft.Right:=OldRight;
if (OldRightLeftLeft<>nil) then
OldRightLeftLeft.Parent:=ANode;
if (OldRightLeftRight<>nil) then
OldRightLeftRight.Parent:=OldRight;
if (OldRightLeft.Balance<=0) then
ANode.Balance:=0
else
ANode.Balance:=-1;
if (OldRightLeft.Balance>=0) then
OldRight.Balance:=0
else
OldRight.Balance:=+1;
OldRightLeft.Balance:=0;
BalanceAfterDelete(OldRightLeft);
end;
end else begin
// Node.Balance=-2
// Node is overweighted to the left
OldLeft:=ANode.Left;
if (OldLeft.Balance<=0) then begin
// rotate right
OldLeftRight:=OldLeft.Right;
if (OldParent<>nil) then begin
if (OldParent.Left=ANode) then
OldParent.Left:=OldLeft
else else
OldParent.Right:=OldLeft; OldLeft.Balance:=-1;
end else OldLeftRight.Balance:=0;
fRoot:=OldLeft; ANode:=OldLeftRight;
ANode.Parent:=OldLeft; end;
ANode.Left:=OldLeftRight;
OldLeft.Parent:=OldParent;
OldLeft.Right:=ANode;
if (OldLeftRight<>nil) then
OldLeftRight.Parent:=ANode;
ANode.Balance:=(-1-OldLeft.Balance); // toggle 0 and -1
Inc(OldLeft.Balance);
BalanceAfterDelete(OldLeft);
end else begin
// OldLeft.Balance = 1
// double rotate left right
OldLeftRight:=OldLeft.Right;
OldLeftRightLeft:=OldLeftRight.Left;
OldLeftRightRight:=OldLeftRight.Right;
if (OldParent<>nil) then begin
if (OldParent.Left=ANode) then
OldParent.Left:=OldLeftRight
else
OldParent.Right:=OldLeftRight;
end else
fRoot:=OldLeftRight;
ANode.Parent:=OldLeftRight;
ANode.Left:=OldLeftRightRight;
OldLeft.Parent:=OldLeftRight;
OldLeft.Right:=OldLeftRightLeft;
OldLeftRight.Parent:=OldParent;
OldLeftRight.Left:=OldLeft;
OldLeftRight.Right:=ANode;
if (OldLeftRightLeft<>nil) then
OldLeftRightLeft.Parent:=OldLeft;
if (OldLeftRightRight<>nil) then
OldLeftRightRight.Parent:=ANode;
if (OldLeftRight.Balance>=0) then
ANode.Balance:=0
else
ANode.Balance:=+1;
if (OldLeftRight.Balance<=0) then
OldLeft.Balance:=0
else
OldLeft.Balance:=-1;
OldLeftRight.Balance:=0;
BalanceAfterDelete(OldLeftRight);
end; end;
end; end;
end; end;