This source file includes following definitions.
- fiboTreeInit
- fiboTreeExit
- fiboTreeFree
- fiboTreeConsolidate
- fiboTreeMin
- fiboTreeAdd
- fiboTreeDel
- fiboTreeCheck2
- fiboTreeCheck
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 #define FIBO
50
51 #include <stdlib.h>
52 #include <memory.h>
53 #include <stdio.h>
54 #include "fibo.h"
55
56
57
58 #ifndef INT
59 #define INT int
60 #endif
61
62 #ifndef errorPrint
63 #define errorPrint(s) fprintf (stderr, s)
64 #endif
65
66 #ifndef memAlloc
67 #define memAlloc malloc
68 #define memSet memset
69 #define memFree free
70 #endif
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 int
86 fiboTreeInit (
87 FiboTree * const treeptr,
88 int (* cmpfptr) (const FiboNode * const, const FiboNode * const))
89 {
90 if ((treeptr->degrtab = (FiboNode **) memAlloc ((sizeof (INT) << 3) * sizeof (FiboNode *))) == NULL)
91 return (1);
92
93 memSet (treeptr->degrtab, 0, (sizeof (INT) << 3) * sizeof (FiboNode *));
94
95 treeptr->rootdat.linkdat.prevptr =
96 treeptr->rootdat.linkdat.nextptr = &treeptr->rootdat;
97 treeptr->cmpfptr = cmpfptr;
98
99 return (0);
100 }
101
102
103
104
105
106
107
108 void
109 fiboTreeExit (
110 FiboTree * const treeptr)
111 {
112 if (treeptr->degrtab != NULL)
113 memFree (treeptr->degrtab);
114 }
115
116
117
118
119
120
121
122
123
124 void
125 fiboTreeFree (
126 FiboTree * const treeptr)
127 {
128 treeptr->rootdat.linkdat.prevptr =
129 treeptr->rootdat.linkdat.nextptr = &treeptr->rootdat;
130 }
131
132
133
134
135
136
137
138
139
140
141 FiboNode *
142 fiboTreeConsolidate (
143 FiboTree * const treeptr)
144 {
145 FiboNode ** restrict degrtab;
146 int degrmax;
147 int degrval;
148 FiboNode * rootptr;
149 FiboNode * nextptr;
150 FiboNode * bestptr;
151
152 degrtab = treeptr->degrtab;
153
154 for (rootptr = treeptr->rootdat.linkdat.nextptr, nextptr = rootptr->linkdat.nextptr, degrmax = 0;
155 rootptr != &treeptr->rootdat; ) {
156 degrval = rootptr->deflval >> 1;
157 #ifdef FIBO_DEBUG
158 if (degrval >= (sizeof (INT) << 3))
159 errorPrint ("fiboTreeConsolidate: invalid node degree");
160 #endif
161 if (degrtab[degrval] == NULL) {
162 if (degrval > degrmax)
163 degrmax = degrval;
164
165 degrtab[degrval] = rootptr;
166 rootptr = nextptr;
167 nextptr = rootptr->linkdat.nextptr;
168 }
169 else {
170 FiboNode * oldrptr;
171 FiboNode * chldptr;
172
173 oldrptr = degrtab[degrval];
174 if (treeptr->cmpfptr (oldrptr, rootptr) <= 0) {
175 oldrptr = rootptr;
176 rootptr = degrtab[degrval];
177 }
178
179 degrtab[degrval] = NULL;
180 fiboTreeUnlink (oldrptr);
181 oldrptr->deflval &= ~1;
182 oldrptr->pareptr = rootptr;
183
184 chldptr = rootptr->chldptr;
185 if (chldptr != NULL) {
186 rootptr->deflval += 2;
187 fiboTreeLinkAfter (chldptr, oldrptr);
188 }
189 else {
190 rootptr->deflval = 2;
191 rootptr->chldptr = oldrptr;
192 oldrptr->linkdat.prevptr =
193 oldrptr->linkdat.nextptr = oldrptr;
194 }
195 }
196 }
197
198 bestptr = NULL;
199 for (degrval = 0; degrval <= degrmax; degrval ++) {
200 if (degrtab[degrval] != NULL) {
201 bestptr = degrtab[degrval];
202 degrtab[degrval] = NULL;
203 degrval ++;
204 break;
205 }
206 }
207 for ( ; degrval <= degrmax; degrval ++) {
208 if (degrtab[degrval] != NULL) {
209 if (treeptr->cmpfptr (degrtab[degrval], bestptr) < 0)
210 bestptr = degrtab[degrval];
211 degrtab[degrval] = NULL;
212 }
213 }
214
215 return (bestptr);
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229 #ifndef fiboTreeMin
230
231 FiboNode *
232 fiboTreeMin (
233 FiboTree * const treeptr)
234 {
235 FiboNode * bestptr;
236
237 bestptr = fiboTreeMinMacro (treeptr);
238
239 #ifdef FIBO_DEBUG
240 fiboTreeCheck (treeptr);
241 #endif
242
243 return (bestptr);
244 }
245
246 #endif
247
248
249
250
251
252
253
254
255 #ifndef fiboTreeAdd
256
257 void
258 fiboTreeAdd (
259 FiboTree * const treeptr,
260 FiboNode * const nodeptr)
261 {
262 fiboTreeAddMacro (treeptr, nodeptr);
263
264 #ifdef FIBO_DEBUG
265 fiboTreeCheck (treeptr);
266 #endif
267 }
268
269 #endif
270
271
272
273
274
275
276
277
278
279 #ifndef fiboTreeDel
280
281 void
282 fiboTreeDel (
283 FiboTree * const treeptr,
284 FiboNode * const nodeptr)
285 {
286 fiboTreeDelMacro (treeptr, nodeptr);
287
288 #ifdef FIBO_DEBUG
289 nodeptr->pareptr =
290 nodeptr->chldptr =
291 nodeptr->linkdat.prevptr =
292 nodeptr->linkdat.nextptr = NULL;
293
294 fiboTreeCheck (treeptr);
295 #endif
296 }
297
298 #endif
299
300
301
302
303
304
305
306
307 #ifdef FIBO_DEBUG
308
309 static
310 int
311 fiboTreeCheck2 (
312 const FiboNode * const nodeptr)
313 {
314 FiboNode * chldptr;
315 int degrval;
316
317 degrval = 0;
318 chldptr = nodeptr->chldptr;
319 if (chldptr != NULL) {
320 do {
321 if (chldptr->linkdat.nextptr->linkdat.prevptr != chldptr) {
322 errorPrint ("fiboTreeCheck: bad child linked list");
323 return (1);
324 }
325
326 if (chldptr->pareptr != nodeptr) {
327 errorPrint ("fiboTreeCheck: bad child parent");
328 return (1);
329 }
330
331 if (fiboTreeCheck2 (chldptr) != 0)
332 return (1);
333
334 degrval ++;
335 chldptr = chldptr->linkdat.nextptr;
336 } while (chldptr != nodeptr->chldptr);
337 }
338
339 if (degrval != (nodeptr->deflval >> 1)) {
340 errorPrint ("fiboTreeCheck2: invalid child information");
341 return (1);
342 }
343
344 return (0);
345 }
346
347 int
348 fiboTreeCheck (
349 const FiboTree * const treeptr)
350 {
351 FiboNode * nodeptr;
352
353 for (nodeptr = treeptr->rootdat.linkdat.nextptr;
354 nodeptr != &treeptr->rootdat; nodeptr = nodeptr->linkdat.nextptr) {
355 if (nodeptr->linkdat.nextptr->linkdat.prevptr != nodeptr) {
356 errorPrint ("fiboTreeCheck: bad root linked list");
357 return (1);
358 }
359
360 if (nodeptr->pareptr != NULL) {
361 errorPrint ("fiboTreeCheck: bad root parent");
362 return (1);
363 }
364
365 if (fiboTreeCheck2 (nodeptr) != 0)
366 return (1);
367 }
368
369 return (0);
370 }
371
372 #endif