2023-01-22 09:40:35 +01:00
|
|
|
#include "vieter_heap_tree.h"
|
|
|
|
|
|
|
|
vieter_heap_node *vieter_heap_node_init() {
|
|
|
|
return calloc(1, sizeof(vieter_heap_node));
|
|
|
|
}
|
|
|
|
|
2023-01-24 12:07:30 +01:00
|
|
|
void vieter_heap_node_free(vieter_heap_node *node) { free(node); }
|
|
|
|
|
|
|
|
void vieter_heap_tree_free(vieter_heap_tree *tree) {
|
|
|
|
uint64_t size = 1;
|
|
|
|
vieter_heap_node **stack =
|
|
|
|
malloc(((uint64_t)1 << tree->order) * sizeof(vieter_heap_node *));
|
|
|
|
stack[0] = tree->root;
|
|
|
|
|
|
|
|
vieter_heap_node *node;
|
|
|
|
|
|
|
|
while (size > 0) {
|
|
|
|
node = stack[size - 1];
|
|
|
|
size--;
|
|
|
|
|
|
|
|
if (node->largest_order != NULL) {
|
|
|
|
stack[size] = node->largest_order;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (node->next_largest_order != NULL) {
|
|
|
|
stack[size] = node->next_largest_order;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
vieter_heap_node_free(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(stack);
|
|
|
|
free(tree);
|
|
|
|
}
|
|
|
|
|
2023-01-22 09:40:35 +01:00
|
|
|
vieter_heap_tree *vieter_heap_tree_init(vieter_heap_node *root,
|
2023-01-24 12:07:30 +01:00
|
|
|
vieter_heap_tree *next, uint8_t order) {
|
2023-01-22 09:40:35 +01:00
|
|
|
vieter_heap_tree *tree = malloc(sizeof(vieter_heap_tree));
|
|
|
|
|
|
|
|
tree->root = root;
|
|
|
|
tree->next = next;
|
|
|
|
tree->order = order;
|
|
|
|
|
|
|
|
return tree;
|
|
|
|
}
|
|
|
|
|
2023-01-22 20:34:05 +01:00
|
|
|
void vieter_heap_tree_swap(vieter_heap_tree *t1, vieter_heap_tree *t2) {
|
|
|
|
vieter_heap_tree temp = {
|
|
|
|
.order = t1->order, .root = t1->root, .next = t1->next};
|
|
|
|
|
|
|
|
t1->order = t2->order;
|
|
|
|
t1->root = t2->root;
|
|
|
|
t1->next = t2->next;
|
|
|
|
|
|
|
|
t2->order = temp.order;
|
|
|
|
t2->root = temp.root;
|
|
|
|
t2->next = temp.next;
|
|
|
|
}
|
|
|
|
|
|
|
|
vieter_heap_tree *vieter_heap_tree_merge_same_order(vieter_heap_tree *tree_a,
|
|
|
|
vieter_heap_tree *tree_b) {
|
|
|
|
vieter_heap_tree *new_tree;
|
|
|
|
|
|
|
|
if (tree_a->root->key <= tree_b->root->key) {
|
|
|
|
new_tree = tree_a;
|
|
|
|
tree_a->root->next_largest_order = tree_a->root->largest_order;
|
|
|
|
tree_a->root->largest_order = tree_b->root;
|
|
|
|
|
|
|
|
free(tree_b);
|
|
|
|
} else {
|
|
|
|
new_tree = tree_b;
|
|
|
|
tree_b->root->next_largest_order = tree_b->root->largest_order;
|
|
|
|
tree_b->root->largest_order = tree_a->root;
|
|
|
|
|
|
|
|
free(tree_a);
|
|
|
|
}
|
|
|
|
|
|
|
|
new_tree->order++;
|
|
|
|
|
|
|
|
return new_tree;
|
|
|
|
}
|
|
|
|
|
2023-01-22 09:40:35 +01:00
|
|
|
vieter_heap_tree *vieter_heap_tree_merge(vieter_heap_tree *tree_a,
|
2023-01-22 20:34:05 +01:00
|
|
|
vieter_heap_tree *tree_b) {
|
2023-01-24 12:07:30 +01:00
|
|
|
vieter_heap_tree *tree, *target, *out;
|
2023-01-22 20:34:05 +01:00
|
|
|
|
|
|
|
if (tree_a->order <= tree_b->order) {
|
|
|
|
target = tree_a;
|
|
|
|
tree = tree_b;
|
|
|
|
} else {
|
|
|
|
target = tree_b;
|
|
|
|
tree = tree_a;
|
|
|
|
}
|
|
|
|
|
|
|
|
vieter_heap_tree *next_tree, *next_target;
|
|
|
|
vieter_heap_tree *previous_target = NULL;
|
|
|
|
|
2023-01-24 12:07:30 +01:00
|
|
|
while (target != NULL && tree != NULL) {
|
2023-01-22 20:34:05 +01:00
|
|
|
if (target->order == tree->order) {
|
|
|
|
next_tree = tree->next;
|
|
|
|
next_target = target->next;
|
|
|
|
|
|
|
|
target = vieter_heap_tree_merge_same_order(target, tree);
|
|
|
|
|
|
|
|
target->next = next_target;
|
|
|
|
|
|
|
|
// If this merge produces a binomial tree whose size is already in
|
2023-01-24 12:07:30 +01:00
|
|
|
// target, it will be the next target. Therefore, we can merge target's
|
2023-01-22 20:34:05 +01:00
|
|
|
// trees until we no longer have a duplicate depth.
|
|
|
|
while (target->next != NULL && target->next->order == target->order) {
|
2023-01-24 12:07:30 +01:00
|
|
|
next_target = target->next->next;
|
2023-01-22 20:34:05 +01:00
|
|
|
target = vieter_heap_tree_merge_same_order(target, target->next);
|
|
|
|
target->next = next_target;
|
|
|
|
}
|
2023-01-24 12:07:30 +01:00
|
|
|
|
|
|
|
if (previous_target != NULL) {
|
|
|
|
previous_target->next = target;
|
|
|
|
} else {
|
|
|
|
out = target;
|
|
|
|
}
|
|
|
|
|
|
|
|
tree = next_tree;
|
2023-01-22 20:34:05 +01:00
|
|
|
} else if (target->order > tree->order) {
|
2023-01-24 12:07:30 +01:00
|
|
|
next_tree = tree->next;
|
|
|
|
|
2023-01-22 20:34:05 +01:00
|
|
|
if (previous_target == NULL) {
|
|
|
|
previous_target = tree;
|
2023-01-24 12:07:30 +01:00
|
|
|
out = tree;
|
2023-01-22 20:34:05 +01:00
|
|
|
} else {
|
|
|
|
previous_target->next = tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
tree->next = target;
|
2023-01-24 12:07:30 +01:00
|
|
|
tree = next_tree;
|
2023-01-22 20:34:05 +01:00
|
|
|
} else {
|
2023-01-24 12:07:30 +01:00
|
|
|
if (previous_target == NULL) {
|
|
|
|
out = target;
|
|
|
|
}
|
|
|
|
|
2023-01-22 20:34:05 +01:00
|
|
|
previous_target = target;
|
|
|
|
target = target->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Append final part of tree to target
|
2023-01-24 12:07:30 +01:00
|
|
|
if (target == NULL) {
|
|
|
|
previous_target->next = tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
vieter_heap_tree *vieter_heap_tree_pop(vieter_heap_tree *tree) {
|
2023-01-22 20:34:05 +01:00
|
|
|
|
|
|
|
}
|