-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinarytrees.pas
151 lines (124 loc) · 2.73 KB
/
binarytrees.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
(*
The Computer Language Benchmarks Game
http://benchmarksgame.alioth.debian.org/
contributed by Vitaly Trifonof based on a contribution of Ales Katona
*)
program BinaryTrees;
type
PNode = ^TNode;
TNode = record
l, r: PNode;
i: Longint;
end;
function CreateNode(l2, r2: PNode; i2: Longint): PNode; inline;
var
tmp : PNode;
begin
new(tmp);
tmp^.l:=l2;
tmp^.r:=r2;
tmp^.i:=i2;
CreateNode := tmp;
end;
(* Destroy node and it subnodes in one procedure *)
procedure DestroyNode(ANode: PNode); inline;
var
LNode, RNode: PNode;
begin
LNode := ANode^.l;
if LNode <> nil then
begin
RNode := ANode^.r;
if LNode^.l <> nil then
begin
DestroyNode(LNode^.l);
DestroyNode(LNode^.r);
dispose(LNode);
DestroyNode(RNode^.l);
DestroyNode(RNode^.r);
dispose(RNode);
end
else
begin
DestroyNode(LNode);
DestroyNode(RNode);
end
end;
dispose(ANode);
end;
(* Left subnodes check in cycle, right recursive *)
function CheckNode(ANode: PNode): Longint; inline;
var
t : LongInt;
begin
t := 0;
while ANode^.l <> nil do
begin
t := t + ANode^.i - CheckNode(ANode^.r);
ANode := ANode^.l
end;
CheckNode := t + ANode^.i;
end;
(*
Create node and it subnodes in one function
make(1,a)=(2I-1)=Ia make(2,Ia-1)=(2(2I-1)-1)=(4I-3)
make(2,Ia) =(2(2I-1)) =(4I-2)
make(1,b)=(2I)=Ib make(2,Ib-1)=(2(2I)-1) =(4I-1)
make(2,Ib) =(2(2I)) =(4I)
*)
function Make(d, i: Longint): PNode;
var
fi: Longint;
begin
case d of
0: Make:=CreateNode(nil, nil, i);
1: Make:=CreateNode(CreateNode(nil, nil, 2*i-1), CreateNode(nil, nil, 2*i),i);
else
begin
d := d - 2; fi := 4*i;
Make:=CreateNode(
CreateNode( Make(d, fi-3),Make(d, fi-2), 2*i-1 ),
CreateNode( Make(d, fi-1),Make(d, fi), 2*i ),
i
);
end;
end
end;
const
mind = 4;
var
maxd : Longint;
strd,
iter,
c, d, i : Longint;
tree, llt : PNode;
begin
if ParamCount = 1 then
Val(ParamStr(1), maxd)
else
maxd := 10;
if maxd < mind+2 then
maxd := mind + 2;
strd:=maxd + 1;
tree:=Make(strd, 0);
Writeln('stretch tree of depth ', strd, chr(9), ' check: ', CheckNode(tree));
DestroyNode(tree);
llt:=Make(maxd, 0);
d:=mind;
while d <= maxd do begin
iter:=1 shl (maxd - d + mind);
c:=0;
for i:=1 to Iter do begin
tree:=Make(d, i);
c:=c + CheckNode(tree);
DestroyNode(tree);
tree:=Make(d, -i);
c:=c + CheckNode(tree);
DestroyNode(tree);
end;
Writeln(2 * Iter, chr(9),' trees of depth ', d, chr(9), ' check: ', c);
d := d + 2;
end;
Writeln('long lived tree of depth ', maxd, chr(9),' check: ', CheckNode(llt));
DestroyNode(llt);
end.