13
TTreeNode<_TParen_, _TChild_: class> = class;
14
TTreeNode<_TNode_: class> = class;
15
TTreeRoot<_TChild_: class> = class;
16
TTreeLeaf<_TParen_: class> = class;
18
TTreeItem = class(TNode)
27
TTreeNode = class(TTreeItem)
29
function GetZero: TTreeNode;
30
procedure SetZero(const Zero_: TTreeNode);
31
function GetIsOrdered: Boolean;
32
class procedure Bind(const C0_, C1_: TTreeNode); overload; inline;
33
class procedure Bind(const C0_, C1_, C2_: TTreeNode); overload; inline;
34
class procedure Bind(const C0_, C1_, C2_, C3_: TTreeNode); overload; inline;
38
_Childs: TMarginArray<TTreeNode>;
41
function GetParen: TTreeNode;
42
procedure SetParen(const Paren_: TTreeNode);
43
function GetOrder: Integer;
44
procedure SetOrder(const Order_: Integer);
45
function GetHead: TTreeNode;
46
function GetTail: TTreeNode;
47
function GetChilds(const I_: Integer): TTreeNode;
48
procedure SetChilds(const I_: Integer; const Child_: TTreeNode);
49
property Zero: TTreeNode read GetZero write SetZero;
50
property IsOrdered: Boolean read GetIsOrdered;
51
procedure FindTo(const Child_: TTreeNode); overload;
52
procedure FindTo(const Order_: Integer); overload;
53
procedure _Insert(const C0_, C1_, C2_: TTreeNode);
55
procedure _InsertHead(const Child_: TTreeNode);
56
procedure _InsertTail(const Child_: TTreeNode);
57
procedure _InsertPrev(const Sibli_: TTreeNode);
58
procedure _InsertNext(const Sibli_: TTreeNode);
60
constructor Create; overload; virtual;
61
constructor Create(const Paren_: TTreeNode); overload; virtual;
62
procedure BeforeDestruction; override;
63
destructor Destroy; override;
64
property Paren: TTreeNode read GetParen write SetParen;
65
property Order: Integer read GetOrder write SetOrder;
66
property Head: TTreeNode read GetHead;
67
property Tail: TTreeNode read GetTail;
68
property Childs[const I_: Integer]: TTreeNode read GetChilds
69
write SetChilds; default;
70
property ChildsN: Integer read _ChildsN;
72
class procedure RemoveChild(const Child_: TTreeNode);
73
procedure DeleteChilds; virtual;
74
procedure InsertHead(const Child_: TTreeNode);
75
procedure InsertTail(const Child_: TTreeNode);
76
procedure InsertPrev(const Sibli_: TTreeNode);
77
procedure InsertNext(const Sibli_: TTreeNode);
78
class procedure Swap(const C1_, C2_: TTreeNode); overload;
79
procedure Swap(const I1_, I2_: Integer); overload;
82
TTreeNode<_TParen_, _TChild_: class> = class(TTreeNode)
85
function GetParen: _TParen_; reintroduce;
86
procedure SetParen(const Paren_: _TParen_); reintroduce;
87
function GetHead: _TChild_; reintroduce;
88
function GetTail: _TChild_; reintroduce;
89
function GetChilds(const I_: Integer): _TChild_; reintroduce;
90
procedure SetChilds(const I_: Integer; const Child_: _TChild_); reintroduce;
92
property Paren: _TParen_ read GetParen write SetParen;
93
property Head: _TChild_ read GetHead;
94
property Tail: _TChild_ read GetTail;
95
property Childs[const I_: Integer]: _TChild_ read GetChilds
96
write SetChilds; default;
99
TTreeNode<_TNode_: class> = class(TTreeNode<_TNode_, _TNode_>)
105
TTreeRoot<_TChild_: class> = class(TTreeNode<_TChild_>)
115
TTreeLeaf<_TParen_: class> = class(TTreeNode<_TParen_>)
125
implementation // --------------------------------------------------------------
127
constructor TTreeItem.Create;
131
_Prev := TTreeNode(Self);
132
_Next := TTreeNode(Self);
135
function TTreeNode.GetZero: TTreeNode;
137
Result := _Childs[-1];
140
procedure TTreeNode.SetZero(const Zero_: TTreeNode);
142
_Childs[-1] := Zero_;
145
// ------------------------------------------------------------------------------
147
function TTreeNode.GetIsOrdered: Boolean;
149
Result := (_Order <= _Paren._MaxOrder) and (_Paren._Childs[_Order] = Self);
152
class procedure TTreeNode.Bind(const C0_, C1_: TTreeNode);
158
class procedure TTreeNode.Bind(const C0_, C1_, C2_: TTreeNode);
164
class procedure TTreeNode.Bind(const C0_, C1_, C2_, C3_: TTreeNode);
171
function TTreeNode.GetParen: TTreeNode;
176
procedure TTreeNode.SetParen(const Paren_: TTreeNode);
180
if Assigned(Paren_) then
181
Paren_._InsertTail(Self);
184
// ------------------------------------------------------------------------------
186
function TTreeNode.GetOrder: Integer;
188
if not IsOrdered then
194
procedure TTreeNode.SetOrder(const Order_: Integer);
196
Swap(Self, _Paren.Childs[Order_]);
199
// ------------------------------------------------------------------------------
201
function TTreeNode.GetHead: TTreeNode;
203
Result := Zero._Next;
206
function TTreeNode.GetTail: TTreeNode;
208
Result := Zero._Prev;
211
// ------------------------------------------------------------------------------
213
function TTreeNode.GetChilds(const I_: Integer): TTreeNode;
215
if I_ > _MaxOrder then
218
Result := _Childs[I_];
221
procedure TTreeNode.SetChilds(const I_: Integer; const Child_: TTreeNode);
227
S := Childs[I_]._Prev;
232
S.InsertNext(Child_);
235
procedure TTreeNode.FindTo(const Child_: TTreeNode);
239
if _ChildsN > _Childs.Count then
240
_Childs.Count := _ChildsN;
242
P := _Childs[_MaxOrder];
249
_Childs[_MaxOrder] := P;
250
P._Order := _MaxOrder;
255
procedure TTreeNode.FindTo(const Order_: Integer);
260
if _ChildsN > _Childs.Count then
261
_Childs.Count := _ChildsN;
263
P := _Childs[_MaxOrder];
265
for I := _MaxOrder + 1 to Order_ do
276
// ------------------------------------------------------------------------------
278
procedure TTreeNode._Insert(const C0_, C1_, C2_: TTreeNode);
287
procedure TTreeNode._Remove;
292
_Paren._MaxOrder := _Order - 1;
298
if _ChildsN * 2 < _Childs.Count then
299
_Childs.Count := _ChildsN;
306
// ------------------------------------------------------------------------------
308
procedure TTreeNode._InsertHead(const Child_: TTreeNode);
310
_Insert(Zero, Child_, Head);
312
_MaxOrder := -1; { if Head.IsOrdered then _MaxOrder := Head._Order - 1; }
315
procedure TTreeNode._InsertTail(const Child_: TTreeNode);
317
_Insert(Tail, Child_, Zero);
319
{ if Tail.IsOrdered then _MaxOrder := Tail._Order; }
322
procedure TTreeNode._InsertPrev(const Sibli_: TTreeNode);
324
_Paren._Insert(_Prev, Sibli_, Self);
327
_Paren._MaxOrder := _Order - 1;
330
procedure TTreeNode._InsertNext(const Sibli_: TTreeNode);
332
_Paren._Insert(Self, Sibli_, _Next);
335
_Paren._MaxOrder := _Order;
338
constructor TTreeNode.Create;
347
_Childs := TMarginArray<TTreeNode>.Create(1, _ChildsN, 0);
349
Zero := TTreeNode(TTreeItem.Create);
354
constructor TTreeNode.Create(const Paren_: TTreeNode);
358
Paren_._InsertTail(Self);
361
procedure TTreeNode.BeforeDestruction;
368
destructor TTreeNode.Destroy;
375
procedure TTreeNode.Remove;
377
if Assigned(_Paren) then
381
class procedure TTreeNode.RemoveChild(const Child_: TTreeNode);
386
// ------------------------------------------------------------------------------
388
procedure TTreeNode.DeleteChilds;
392
for N := 1 to _ChildsN do
396
// ------------------------------------------------------------------------------
398
procedure TTreeNode.InsertHead(const Child_: TTreeNode);
404
procedure TTreeNode.InsertTail(const Child_: TTreeNode);
410
procedure TTreeNode.InsertPrev(const Sibli_: TTreeNode);
416
procedure TTreeNode.InsertNext(const Sibli_: TTreeNode);
422
// ------------------------------------------------------------------------------
424
class procedure TTreeNode.Swap(const C1_, C2_: TTreeNode);
426
P1, P2, C1n, C1u, C2n, C2u: TTreeNode;
454
Bind(C1n, C2_, C1_, C2u)
455
else if C1_ = C2u then
456
Bind(C2n, C1_, C2_, C1u)
465
P1._Childs[I1] := C2_;
471
P2._Childs[I2] := C1_;
476
procedure TTreeNode.Swap(const I1_, I2_: Integer);
478
Swap(Childs[I1_], Childs[I2_]);
481
function TTreeNode<_TParen_, _TChild_>.GetParen: _TParen_;
483
Result := _TParen_(inherited GetParen);
486
procedure TTreeNode<_TParen_, _TChild_>.SetParen(const Paren_: _TParen_);
488
inherited SetParen(TTreeNode(Paren_));
491
// ------------------------------------------------------------------------------
493
function TTreeNode<_TParen_, _TChild_>.GetHead: _TChild_;
495
Result := _TChild_(inherited GetHead);
498
function TTreeNode<_TParen_, _TChild_>.GetTail: _TChild_;
500
Result := _TChild_(inherited GetTail);
503
// ------------------------------------------------------------------------------
505
function TTreeNode<_TParen_, _TChild_>.GetChilds(const I_: Integer): _TChild_;
507
Result := _TChild_(inherited GetChilds(I_));
510
procedure TTreeNode<_TParen_, _TChild_>.SetChilds(const I_: Integer;
511
const Child_: _TChild_);
513
inherited SetChilds(I_, TTreeNode(Child_));
516
initialization // --------------------------------------------------------------