mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-22 14:59:17 +02:00
avglvltree: replaced recursive calls with simple loop
git-svn-id: trunk@36132 -
This commit is contained in:
parent
91f11c0ca2
commit
377971d392
@ -963,148 +963,154 @@ begin
|
||||
end;
|
||||
|
||||
procedure TAvgLvlTree.BalanceAfterInsert(ANode: TAvgLvlTreeNode);
|
||||
var OldParent, OldParentParent, OldRight, OldRightLeft, OldRightRight, OldLeft,
|
||||
OldLeftLeft, OldLeftRight: TAvgLvlTreeNode;
|
||||
var
|
||||
OldParent, OldParentParent, OldRight, OldRightLeft, OldRightRight, OldLeft,
|
||||
OldLeftLeft, OldLeftRight: TAvgLvlTreeNode;
|
||||
begin
|
||||
OldParent:=ANode.Parent;
|
||||
if (OldParent=nil) then exit;
|
||||
if (OldParent.Left=ANode) then begin
|
||||
// Node is left son
|
||||
dec(OldParent.Balance);
|
||||
if (OldParent.Balance=0) then exit;
|
||||
if (OldParent.Balance=-1) then begin
|
||||
BalanceAfterInsert(OldParent);
|
||||
exit;
|
||||
end;
|
||||
// OldParent.Balance=-2
|
||||
if (ANode.Balance=-1) then begin
|
||||
// rotate
|
||||
OldRight:=ANode.Right;
|
||||
OldParentParent:=OldParent.Parent;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// OldParent has GrandParent. GrandParent gets new child
|
||||
if (OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=ANode
|
||||
else
|
||||
OldParentParent.Right:=ANode;
|
||||
end else begin
|
||||
// OldParent was fRoot node. New fRoot node
|
||||
fRoot:=ANode;
|
||||
while (OldParent<>nil) do begin
|
||||
if (OldParent.Left=ANode) then begin
|
||||
// Node is left son
|
||||
dec(OldParent.Balance);
|
||||
if (OldParent.Balance=0) then exit;
|
||||
if (OldParent.Balance=-1) then begin
|
||||
ANode:=OldParent;
|
||||
OldParent:=ANode.Parent;
|
||||
continue;
|
||||
end;
|
||||
ANode.Parent:=OldParentParent;
|
||||
ANode.Right:=OldParent;
|
||||
OldParent.Parent:=ANode;
|
||||
OldParent.Left:=OldRight;
|
||||
if (OldRight<>nil) then
|
||||
OldRight.Parent:=OldParent;
|
||||
ANode.Balance:=0;
|
||||
OldParent.Balance:=0;
|
||||
end else begin
|
||||
// Node.Balance = +1
|
||||
// double rotate
|
||||
OldParentParent:=OldParent.Parent;
|
||||
OldRight:=ANode.Right;
|
||||
OldRightLeft:=OldRight.Left;
|
||||
OldRightRight:=OldRight.Right;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// OldParent has GrandParent. GrandParent gets new child
|
||||
if (OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=OldRight
|
||||
else
|
||||
OldParentParent.Right:=OldRight;
|
||||
end else begin
|
||||
// OldParent was fRoot node. new fRoot node
|
||||
fRoot:=OldRight;
|
||||
end;
|
||||
OldRight.Parent:=OldParentParent;
|
||||
OldRight.Left:=ANode;
|
||||
OldRight.Right:=OldParent;
|
||||
ANode.Parent:=OldRight;
|
||||
ANode.Right:=OldRightLeft;
|
||||
OldParent.Parent:=OldRight;
|
||||
OldParent.Left:=OldRightRight;
|
||||
if (OldRightLeft<>nil) then
|
||||
OldRightLeft.Parent:=ANode;
|
||||
if (OldRightRight<>nil) then
|
||||
OldRightRight.Parent:=OldParent;
|
||||
if (OldRight.Balance<=0) then
|
||||
ANode.Balance:=0
|
||||
else
|
||||
ANode.Balance:=-1;
|
||||
if (OldRight.Balance=-1) then
|
||||
OldParent.Balance:=1
|
||||
else
|
||||
// OldParent.Balance=-2
|
||||
if (ANode.Balance=-1) then begin
|
||||
// rotate
|
||||
OldRight:=ANode.Right;
|
||||
OldParentParent:=OldParent.Parent;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// OldParent has GrandParent. GrandParent gets new child
|
||||
if (OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=ANode
|
||||
else
|
||||
OldParentParent.Right:=ANode;
|
||||
end else begin
|
||||
// OldParent was fRoot node. New fRoot node
|
||||
fRoot:=ANode;
|
||||
end;
|
||||
ANode.Parent:=OldParentParent;
|
||||
ANode.Right:=OldParent;
|
||||
OldParent.Parent:=ANode;
|
||||
OldParent.Left:=OldRight;
|
||||
if (OldRight<>nil) then
|
||||
OldRight.Parent:=OldParent;
|
||||
ANode.Balance:=0;
|
||||
OldParent.Balance:=0;
|
||||
OldRight.Balance:=0;
|
||||
end;
|
||||
end else begin
|
||||
// Node is right son
|
||||
Inc(OldParent.Balance);
|
||||
if (OldParent.Balance=0) then exit;
|
||||
if (OldParent.Balance=+1) then begin
|
||||
BalanceAfterInsert(OldParent);
|
||||
end else begin
|
||||
// Node.Balance = +1
|
||||
// double rotate
|
||||
OldParentParent:=OldParent.Parent;
|
||||
OldRight:=ANode.Right;
|
||||
OldRightLeft:=OldRight.Left;
|
||||
OldRightRight:=OldRight.Right;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// OldParent has GrandParent. GrandParent gets new child
|
||||
if (OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=OldRight
|
||||
else
|
||||
OldParentParent.Right:=OldRight;
|
||||
end else begin
|
||||
// OldParent was fRoot node. new fRoot node
|
||||
fRoot:=OldRight;
|
||||
end;
|
||||
OldRight.Parent:=OldParentParent;
|
||||
OldRight.Left:=ANode;
|
||||
OldRight.Right:=OldParent;
|
||||
ANode.Parent:=OldRight;
|
||||
ANode.Right:=OldRightLeft;
|
||||
OldParent.Parent:=OldRight;
|
||||
OldParent.Left:=OldRightRight;
|
||||
if (OldRightLeft<>nil) then
|
||||
OldRightLeft.Parent:=ANode;
|
||||
if (OldRightRight<>nil) then
|
||||
OldRightRight.Parent:=OldParent;
|
||||
if (OldRight.Balance<=0) then
|
||||
ANode.Balance:=0
|
||||
else
|
||||
ANode.Balance:=-1;
|
||||
if (OldRight.Balance=-1) then
|
||||
OldParent.Balance:=1
|
||||
else
|
||||
OldParent.Balance:=0;
|
||||
OldRight.Balance:=0;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
// OldParent.Balance = +2
|
||||
if(ANode.Balance=+1) then begin
|
||||
// rotate
|
||||
OldLeft:=ANode.Left;
|
||||
OldParentParent:=OldParent.Parent;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// Parent has GrandParent . GrandParent gets new child
|
||||
if(OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=ANode
|
||||
else
|
||||
OldParentParent.Right:=ANode;
|
||||
end else begin
|
||||
// OldParent was fRoot node . new fRoot node
|
||||
fRoot:=ANode;
|
||||
end;
|
||||
ANode.Parent:=OldParentParent;
|
||||
ANode.Left:=OldParent;
|
||||
OldParent.Parent:=ANode;
|
||||
OldParent.Right:=OldLeft;
|
||||
if (OldLeft<>nil) then
|
||||
OldLeft.Parent:=OldParent;
|
||||
ANode.Balance:=0;
|
||||
OldParent.Balance:=0;
|
||||
end else begin
|
||||
// Node.Balance = -1
|
||||
// double rotate
|
||||
OldLeft:=ANode.Left;
|
||||
OldParentParent:=OldParent.Parent;
|
||||
OldLeftLeft:=OldLeft.Left;
|
||||
OldLeftRight:=OldLeft.Right;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// OldParent has GrandParent . GrandParent gets new child
|
||||
if (OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=OldLeft
|
||||
else
|
||||
OldParentParent.Right:=OldLeft;
|
||||
end else begin
|
||||
// OldParent was fRoot node . new fRoot node
|
||||
fRoot:=OldLeft;
|
||||
// Node is right son
|
||||
Inc(OldParent.Balance);
|
||||
if (OldParent.Balance=0) then exit;
|
||||
if (OldParent.Balance=+1) then begin
|
||||
ANode:=OldParent;
|
||||
OldParent:=ANode.Parent;
|
||||
continue;
|
||||
end;
|
||||
OldLeft.Parent:=OldParentParent;
|
||||
OldLeft.Left:=OldParent;
|
||||
OldLeft.Right:=ANode;
|
||||
ANode.Parent:=OldLeft;
|
||||
ANode.Left:=OldLeftRight;
|
||||
OldParent.Parent:=OldLeft;
|
||||
OldParent.Right:=OldLeftLeft;
|
||||
if (OldLeftLeft<>nil) then
|
||||
OldLeftLeft.Parent:=OldParent;
|
||||
if (OldLeftRight<>nil) then
|
||||
OldLeftRight.Parent:=ANode;
|
||||
if (OldLeft.Balance>=0) then
|
||||
ANode.Balance:=0
|
||||
else
|
||||
ANode.Balance:=+1;
|
||||
if (OldLeft.Balance=+1) then
|
||||
OldParent.Balance:=-1
|
||||
else
|
||||
// OldParent.Balance = +2
|
||||
if(ANode.Balance=+1) then begin
|
||||
// rotate
|
||||
OldLeft:=ANode.Left;
|
||||
OldParentParent:=OldParent.Parent;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// Parent has GrandParent . GrandParent gets new child
|
||||
if(OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=ANode
|
||||
else
|
||||
OldParentParent.Right:=ANode;
|
||||
end else begin
|
||||
// OldParent was fRoot node . new fRoot node
|
||||
fRoot:=ANode;
|
||||
end;
|
||||
ANode.Parent:=OldParentParent;
|
||||
ANode.Left:=OldParent;
|
||||
OldParent.Parent:=ANode;
|
||||
OldParent.Right:=OldLeft;
|
||||
if (OldLeft<>nil) then
|
||||
OldLeft.Parent:=OldParent;
|
||||
ANode.Balance:=0;
|
||||
OldParent.Balance:=0;
|
||||
OldLeft.Balance:=0;
|
||||
end else begin
|
||||
// Node.Balance = -1
|
||||
// double rotate
|
||||
OldLeft:=ANode.Left;
|
||||
OldParentParent:=OldParent.Parent;
|
||||
OldLeftLeft:=OldLeft.Left;
|
||||
OldLeftRight:=OldLeft.Right;
|
||||
if (OldParentParent<>nil) then begin
|
||||
// OldParent has GrandParent . GrandParent gets new child
|
||||
if (OldParentParent.Left=OldParent) then
|
||||
OldParentParent.Left:=OldLeft
|
||||
else
|
||||
OldParentParent.Right:=OldLeft;
|
||||
end else begin
|
||||
// OldParent was fRoot node . new fRoot node
|
||||
fRoot:=OldLeft;
|
||||
end;
|
||||
OldLeft.Parent:=OldParentParent;
|
||||
OldLeft.Left:=OldParent;
|
||||
OldLeft.Right:=ANode;
|
||||
ANode.Parent:=OldLeft;
|
||||
ANode.Left:=OldLeftRight;
|
||||
OldParent.Parent:=OldLeft;
|
||||
OldParent.Right:=OldLeftLeft;
|
||||
if (OldLeftLeft<>nil) then
|
||||
OldLeftLeft.Parent:=OldParent;
|
||||
if (OldLeftRight<>nil) then
|
||||
OldLeftRight.Parent:=ANode;
|
||||
if (OldLeft.Balance>=0) then
|
||||
ANode.Balance:=0
|
||||
else
|
||||
ANode.Balance:=+1;
|
||||
if (OldLeft.Balance=+1) then
|
||||
OldParent.Balance:=-1
|
||||
else
|
||||
OldParent.Balance:=0;
|
||||
OldLeft.Balance:=0;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user