]>
git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_bintree.c
3 #include "ospf6_bintree.h"
5 static struct bintree_node
*
6 bintree_lookup_node_min (struct bintree_node
*subroot
)
8 struct bintree_node
*node
;
19 static struct bintree_node
*
20 bintree_lookup_node_max (struct bintree_node
*subroot
)
22 struct bintree_node
*node
;
24 assert (subroot
!= NULL
);
26 while (node
->bl_right
)
27 node
= node
->bl_right
;
32 bintree_lookup (void *data
, struct bintree
*tree
)
35 struct bintree_node
*node
;
42 cmp
= (*tree
->cmp
) (node
->data
, data
);
44 cmp
= (node
->data
- data
);
51 else /* if (cmp < 0) */
52 node
= node
->bl_right
;
62 bintree_lookup_min (struct bintree
*tree
)
64 struct bintree_node
*node
;
65 node
= bintree_lookup_node_min (tree
->root
);
72 bintree_lookup_max (struct bintree
*tree
)
74 struct bintree_node
*node
;
75 node
= bintree_lookup_node_max (tree
->root
);
82 bintree_add (void *data
, struct bintree
*tree
)
85 struct bintree_node
*node
, *parent
;
93 cmp
= (*tree
->cmp
) (node
->data
, data
);
95 cmp
= (node
->data
- data
);
102 node
= node
->bl_left
;
103 else /* if (cmp < 0) */
104 node
= node
->bl_right
;
110 node
= malloc (sizeof (struct bintree_node
));
111 memset (node
, 0, sizeof (struct bintree_node
));
117 node
->parent
= parent
;
122 node
->parent_link
= BL_LEFT
;
123 parent
->bl_left
= node
;
125 else /* if (cmp < 0) */
127 node
->parent_link
= BL_RIGHT
;
128 parent
->bl_right
= node
;
139 bintree_remove_nochild (struct bintree_node
*node
)
141 assert (node
->bl_left
== NULL
&& node
->bl_right
== NULL
);
143 if (node
->parent
== NULL
)
144 node
->tree
->root
= NULL
;
146 node
->parent
->link
[node
->parent_link
] = NULL
;
150 bintree_remove_onechild (struct bintree_node
*node
)
152 assert ((node
->bl_left
== NULL
&& node
->bl_right
!= NULL
) ||
153 (node
->bl_left
!= NULL
&& node
->bl_right
== NULL
));
157 if (node
->parent
== NULL
)
159 node
->tree
->root
= node
->bl_left
;
160 node
->bl_left
->parent
= NULL
;
164 node
->parent
->link
[node
->parent_link
] = node
->bl_left
;
165 node
->bl_left
->parent
= node
->parent
;
166 node
->bl_left
->parent_link
= node
->parent_link
;
169 else if (node
->bl_right
)
171 if (node
->parent
== NULL
)
173 node
->tree
->root
= node
->bl_right
;
174 node
->bl_right
->parent
= NULL
;
178 node
->parent
->link
[node
->parent_link
] = node
->bl_right
;
179 node
->bl_right
->parent
= node
->parent
;
180 node
->bl_right
->parent_link
= node
->parent_link
;
188 bintree_remove (void *data
, struct bintree
*tree
)
191 struct bintree_node
*node
;
198 cmp
= (*tree
->cmp
) (node
->data
, data
);
200 cmp
= (node
->data
- data
);
206 node
= node
->bl_left
;
207 else /* if (cmp < 0) */
208 node
= node
->bl_right
;
214 if (node
->bl_left
== NULL
&& node
->bl_right
== NULL
)
216 bintree_remove_nochild (node
);
222 if ((node
->bl_left
== NULL
&& node
->bl_right
!= NULL
) ||
223 (node
->bl_left
!= NULL
&& node
->bl_right
== NULL
))
225 bintree_remove_onechild (node
);
231 if (node
->bl_left
!= NULL
&& node
->bl_right
!= NULL
)
233 struct bintree_node
*successor
;
235 /* find successor of the removing node */
236 successor
= bintree_lookup_node_min (node
->bl_right
);
238 /* remove successor from tree */
239 if (successor
->bl_right
)
240 bintree_remove_onechild (successor
);
242 bintree_remove_nochild (successor
);
244 /* swap removing node with successor */
245 successor
->parent
= node
->parent
;
246 successor
->parent_link
= node
->parent_link
;
247 successor
->bl_left
= node
->bl_left
;
248 successor
->bl_right
= node
->bl_right
;
250 /* if the successor was the node->bl_right itself,
251 bintree_remove_**child may touch node->bl_right,
252 so only the successor->bl_right may be NULL
253 by above assignment */
254 successor
->bl_left
->parent
= successor
;
255 if (successor
->bl_right
)
256 successor
->bl_right
->parent
= successor
;
258 if (successor
->parent
== NULL
)
259 tree
->root
= successor
;
261 successor
->parent
->link
[successor
->parent_link
] = successor
;
272 /* in-order traversal */
275 bintree_head (struct bintree
*tree
, struct bintree_node
*node
)
277 struct bintree_node
*head
;
279 head
= bintree_lookup_node_min (tree
->root
);
283 node
->bl_left
= NULL
;
284 node
->bl_right
= NULL
;
289 node
->tree
= head
->tree
;
290 node
->parent
= head
->parent
;
291 node
->parent_link
= head
->parent_link
;
292 node
->bl_left
= head
->bl_left
;
293 node
->bl_right
= head
->bl_right
;
294 node
->data
= head
->data
;
298 bintree_end (struct bintree_node
*node
)
300 if (node
->parent
|| node
->bl_left
|| node
->bl_right
|| node
->data
)
305 #define GOTO_PROCED_SUBTREE_TOP(node) \
306 while (node->parent && node->parent->bl_right && \
307 node->parent->bl_right->data == node->data) \
309 node->data = node->parent->data; \
310 node->bl_left = node->parent->bl_left; \
311 node->bl_right = node->parent->bl_right; \
312 node->parent_link = node->parent->parent_link; \
313 node->parent = node->parent->parent; \
317 bintree_next (struct bintree_node
*node
)
319 struct bintree_node
*next
= NULL
;
321 /* if node have just been removed, current point should have just been
322 replaced with its successor. that certainly will not be processed
323 yet, so process it */
324 if (node
->parent
== NULL
)
326 if (node
->tree
->root
== NULL
)
328 assert (node
->tree
->count
== 0);
330 node
->bl_left
= NULL
;
331 node
->bl_right
= NULL
;
335 else if (node
->tree
->root
->data
!= node
->data
)
336 next
= node
->tree
->root
;
338 else if (node
->parent
->link
[node
->parent_link
] == NULL
)
340 if (node
->parent_link
== BL_LEFT
)
344 GOTO_PROCED_SUBTREE_TOP (node
);
348 else if (node
->parent
->link
[node
->parent_link
]->data
!= node
->data
)
349 next
= node
->parent
->link
[node
->parent_link
];
354 next
= bintree_lookup_node_min (node
->bl_right
);
357 GOTO_PROCED_SUBTREE_TOP (node
);
364 node
->tree
= next
->tree
;
365 node
->parent
= next
->parent
;
366 node
->parent_link
= next
->parent_link
;
367 node
->bl_left
= next
->bl_left
;
368 node
->bl_right
= next
->bl_right
;
369 node
->data
= next
->data
;
374 node
->bl_left
= NULL
;
375 node
->bl_right
= NULL
;
383 struct bintree
*tree
;
385 tree
= malloc (sizeof (struct bintree
));
386 memset (tree
, 0, sizeof (struct bintree
));
392 bintree_delete (struct bintree
*tree
)
394 struct bintree_node node
;
396 for (bintree_head (tree
, &node
); ! bintree_end (&node
);
397 bintree_next (&node
))
398 bintree_remove (node
.data
, tree
);
400 assert (tree
->count
== 0);
407 bintree_print_sub (void (*print
) (int, void *), struct bintree_node
*subroot
)
412 if (subroot
->bl_right
)
415 bintree_print_sub (print
, subroot
->bl_right
);
419 (*print
) (indent_num
, subroot
->data
);
421 if (subroot
->bl_left
)
424 bintree_print_sub (print
, subroot
->bl_left
);
430 bintree_print (void (*print
) (int, void *), struct bintree
*tree
)
433 bintree_print_sub (print
, tree
->root
);