tupperware: avl: add merging functions

This commit is contained in:
Bruno BELANYI 2020-11-24 19:43:34 +01:00
parent d35bd77e20
commit 96971e9c8e
2 changed files with 51 additions and 6 deletions

View file

@ -57,10 +57,4 @@ void avl_merge(struct avl *tree, struct avl *more);
void avl_update(struct avl *tree, struct avl *more);
void avl_merge_all(struct avl *tree, struct avl *more);
void avl_prefix_map(struct avl *tree, avl_map_f map, void *cookie);
void avl_infix_map(struct avl *tree, avl_map_f map, void *cookie);
void avl_postfix_map(struct avl *tree, avl_map_f map, void *cookie);
void avl_map_between(const struct avl *tree,
struct avl_node *inter[2], avl_map_f map, void *cookie);
#endif /* !TUPPERWARE_AVL_H */

View file

@ -416,3 +416,54 @@ size_t avl_height(const struct avl *tree) {
return avl_height_helper(tree->root);
}
void avl_merge(struct avl *tree, struct avl *more) {
if (!tree || !more)
return;
struct avl tmp = {
more->cmp,
more->cookie,
NULL,
};
while (more->root) {
struct avl_node *v = more->root;
avl_remove_at(more, more->root); // Won't fail
if ((!avl_insert(tree, v, NULL))) // Keep old value
avl_insert_multi(&tmp, v); // Be conservative when reinserting
}
more->root = tmp.root;
}
void avl_update(struct avl *tree, struct avl *more) {
if (!tree || !more)
return;
struct avl tmp = {
more->cmp,
more->cookie,
NULL,
};
while (more->root) {
struct avl_node *v = more->root;
avl_remove_at(more, more->root); // Won't fail
if ((v = avl_insert_or_update(tree, v))) // Keep new value
avl_insert_multi(&tmp, v); // Be conservative when reinserting
}
more->root = tmp.root;
}
void avl_merge_all(struct avl *tree, struct avl *more) {
if (!tree || !more)
return;
while (more->root) {
struct avl_node *v = more->root;
avl_remove_at(more, more->root); // Won't fail
avl_insert_multi(tree, v); // Keep all values
}
}