diff --git a/Tampermonkey.js b/Tampermonkey.js new file mode 100644 index 0000000000000000000000000000000000000000..69bd604ebc5022d001acc7ff006391442dbdbec9 --- /dev/null +++ b/Tampermonkey.js @@ -0,0 +1,47 @@ +window.addEventListener('load', function() { + var table_AlgorithmSpecificControls = document.getElementById("AlgorithmSpecificControls"); + var insert_input = table_AlgorithmSpecificControls.children[0].children[0]; + var insert_button = table_AlgorithmSpecificControls.children[1].children[0]; + var delete_input = table_AlgorithmSpecificControls.children[2].children[0]; + var delete_button = table_AlgorithmSpecificControls.children[3].children[0]; + + var table_GeneralAnimationControls = document.getElementById("GeneralAnimationControls"); + var skip_button = table_GeneralAnimationControls.children[4].children[0]; + + function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + async function insert_keys(keys) { + for (var i = 0; i < keys.length; i++) { + insert_input.value = keys[i]; + insert_button.click(); + skip_button.click(); + await timeout(10); + } + } + + async function delete_keys(keys) { + for (var i = 0; i < keys.length; i++) { + delete_input.value = keys[i]; + delete_button.click(); + skip_button.click(); + await timeout(10); + } + } + + async function do_stuff() { + var inputs_MaxDegree = document.getElementsByName("MaxDegree"); + var input_MaxDegree = inputs_MaxDegree[2]; + input_MaxDegree.checked = true; + input_MaxDegree.click(); + await timeout(500); + + await insert_keys([8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55]); + await delete_keys([65, 57, 47, 28, 51]); + await insert_keys([100]); + await delete_keys([48, 41, 60, 5, 8, 21, 86, 100, 88, 95, 49, 56, 55]); + } + + do_stuff(); +}, false); diff --git a/src/Array.c b/src/Array.c index 4af759db9d2fd5369bbb10c2e14c3c2b6e67a1b0..6c4eb3f330fc6745a361662f833deae0882a1849 100644 --- a/src/Array.c +++ b/src/Array.c @@ -96,13 +96,6 @@ void IntegerArray_delete_at_index(IntegerArray *array, int index) { array->size--; } -int IntegerArray_delete_sorted(IntegerArray *array, uint64_t item) { - int index; - IntegerArray_binary_search(array, item, &index); - IntegerArray_delete_at_index(array, index); - return index; -} - void IntegerArray_print(IntegerArray *array) { printf("["); @@ -164,6 +157,12 @@ void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index) { array->size--; } +BPTreeNode *BPTreeNodeArray_pop(BPTreeNodeArray *array) { + BPTreeNode *item = array->items[array->size - 1]; + BPTreeNodeArray_delete_at_index(array, array->size - 1); + return item; +} + void BPTreeNodeArray_clear(BPTreeNodeArray *array) { array->size = 0; } diff --git a/src/Array.h b/src/Array.h index 895cbf4aa8c399c87c142fa1339cb161d67be3af..2b68403970c2e287f1bdbb91c91293183b37b887 100644 --- a/src/Array.h +++ b/src/Array.h @@ -21,7 +21,6 @@ void IntegerArray_insert_at_index(IntegerArray *array, int index, uint64_t item) void IntegerArray_append(IntegerArray *array, uint64_t item); bool IntegerArray_binary_search(IntegerArray *array, uint64_t item, int *index); void IntegerArray_delete_at_index(IntegerArray *array, int index); -int IntegerArray_delete_sorted(IntegerArray *array, uint64_t item); void IntegerArray_print(IntegerArray *array); void IntegerArray_clear(IntegerArray *array); void IntegerArray_copy(IntegerArray *src, IntegerArray *dest); @@ -41,6 +40,7 @@ void BPTreeNodeArray_destroy(BPTreeNodeArray **array); void BPTreeNodeArray_insert_at_index(BPTreeNodeArray *array, int index, BPTreeNode *item); void BPTreeNodeArray_append(BPTreeNodeArray *array, BPTreeNode *item); void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index); +BPTreeNode *BPTreeNodeArray_pop(BPTreeNodeArray *array); void BPTreeNodeArray_clear(BPTreeNodeArray *array); void BPTreeNodeArray_copy(BPTreeNodeArray *src, BPTreeNodeArray *dest); diff --git a/src/BPTree.c b/src/BPTree.c index 5f454b37c6ba4d678d565c6923beed0d9b7e987b..924491d7d03b0d6ed794abc7706eecfb481cb8cd 100644 --- a/src/BPTree.c +++ b/src/BPTree.c @@ -70,11 +70,11 @@ void BPTree_print(BPTreeNode *root, int depth) { } IntegerArray_print(root->keys); - for (int i = 0; i < depth; i++) { - printf(" "); - } - printf("*"); - IntegerArray_print(root->data); + // for (int i = 0; i < depth; i++) { + // printf(" "); + // } + // printf("*"); + // IntegerArray_print(root->data); for (int i = 0; i < root->children->size; i++) { BPTree_print(root->children->items[i], depth + 1); @@ -227,8 +227,7 @@ static void insert_full(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode * if (node == root) { grow(root, median_value, split_right_node); } else { - BPTreeNode *parent = parents->items[parents->size - 1]; - BPTreeNodeArray_delete_at_index(parents, parents->size - 1); + BPTreeNode *parent = BPTreeNodeArray_pop(parents); if (has_maximum_keys(parent)) { // 0 is passed instead of data because the recursion is necessarily done on an internal node. @@ -281,7 +280,7 @@ static void steal_leaf(BPTreeNode *parent, BPTreeNode *node, int child_index, BP static void _merge(BPTreeNode *parent, BPTreeNode *main_node, BPTreeNode *secondary_node, int pivot_index); static void merge(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling); static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node); -static void _BPTree_delete(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key); +static void deletion_rebalance(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key); static uint64_t find_smallest_key(BPTreeNode *root) { if (root->is_leaf) { @@ -414,17 +413,11 @@ static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node) { return parent->children->items[child_index - 1]; } -static void _BPTree_delete(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key) { +static void deletion_rebalance(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key) { BPTreeNode *parent = NULL; if (parents->size > 0) { - parent = parents->items[parents->size - 1]; - BPTreeNodeArray_delete_at_index(parents, parents->size - 1); - } - - if (node->is_leaf) { - int index = IntegerArray_delete_sorted(node->keys, key); - IntegerArray_delete_at_index(node->data, index); + parent = BPTreeNodeArray_pop(parents); } if (node != root && node->keys->size < node->order) { @@ -447,14 +440,23 @@ static void _BPTree_delete(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNod } } + if (parent != NULL) { + deletion_rebalance(root, parents, parent, key); + } +} + +static void replace_deleted_key_internal(BPTreeNodeArray *parents, int i, uint64_t key) { + if (i < 0) { + return; + } + + BPTreeNode *node = parents->items[i]; int index; - if (!node->is_leaf && node->children->size > 0 && IntegerArray_binary_search(node->keys, key, &index)) { + if (IntegerArray_binary_search(node->keys, key, &index)) { node->keys->items[index] = find_smallest_key(node->children->items[index + 1]); } - if (parent != NULL) { - _BPTree_delete(root, parents, parent, key); - } + replace_deleted_key_internal(parents, i - 1, key); } void BPTree_delete(BPTreeNode *root, uint64_t key) { @@ -467,6 +469,11 @@ void BPTree_delete(BPTreeNode *root, uint64_t key) { return; } - _BPTree_delete(root, parents, leaf, key); + IntegerArray_delete_at_index(leaf->keys, index); + IntegerArray_delete_at_index(leaf->data, index); + + replace_deleted_key_internal(parents, parents->size - 1, key); + deletion_rebalance(root, parents, leaf, key); + BPTreeNodeArray_destroy(&parents); } diff --git a/src/main.c b/src/main.c index fde343156b3b669c1bb6c1e8c70669dcac0bd2e3..ba9e5521f77ada166060ffa30c65f07e169b74be 100644 --- a/src/main.c +++ b/src/main.c @@ -38,6 +38,18 @@ int main() { BPTree_delete(root, 48); BPTree_delete(root, 41); BPTree_delete(root, 60); + BPTree_delete(root, 5); + BPTree_delete(root, 8); + BPTree_delete(root, 21); + + BPTree_delete(root, 86); + BPTree_delete(root, 100); + BPTree_delete(root, 88); + BPTree_delete(root, 95); + BPTree_delete(root, 49); + BPTree_delete(root, 56); + BPTree_delete(root, 55); + BPTree_print(root, 0); IntegerArray_destroy(&keys);