From: Michael D. Lowis Date: Sun, 12 Apr 2015 18:30:33 +0000 (-0400) Subject: Finished splaytree implementation X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=9ee55ca01cab1b665a1f996e49cddae2c74bc66d;p=archive%2Fatc.git Finished splaytree implementation --- diff --git a/source/.DS_Store b/source/.DS_Store new file mode 100644 index 0000000..2483a16 Binary files /dev/null and b/source/.DS_Store differ diff --git a/source/runtime/splaytree.c b/source/runtime/splaytree.c index 65d658a..b3611b4 100644 --- a/source/runtime/splaytree.c +++ b/source/runtime/splaytree.c @@ -4,30 +4,22 @@ */ #include "splaytree.h" #include -#include +#include -static node_t* create_node(void* value) +static node_t* create_node(void* value, node_t* left, node_t* right) { - node_t* node = (node_t*)malloc(sizeof(node_t*)); + node_t* node = (node_t*)malloc(sizeof(node_t)); node->value = value; - node->left = NULL; - node->right = NULL; + node->left = left; + node->right = right; return node; } -static node_t** next_node(splaytree_t* tree, node_t* curr, uintptr_t address) -{ - if (tree->compare(address, curr->value) < 0) - return &(curr->left); - else - return &(curr->right); -} - static void destroy_node(splaytree_t* tree, node_t* node) { if (NULL != node) { + //tree->destroy(node->value); destroy_node(tree, node->left); destroy_node(tree, node->right); - //tree->destroy(node->value); free(node); } } @@ -49,22 +41,6 @@ static node_t* rotate(node_t* node, direction_t direction){ return pivot; } -void print_tree(node_t* tree) { - if (tree) { - printf("(%lu ", (uintptr_t)tree->value); - if (tree->left) { - print_tree(tree->left); - printf(" "); - } else - printf("nil "); - if (tree->right) - print_tree(tree->right); - else - printf("nil"); - printf(")"); - } -} - static void splay(splaytree_t* tree, uintptr_t key) { node_t subroots = {0, 0, 0}; node_t* subleft = &subroots; @@ -119,7 +95,7 @@ splaytree_t* splaytree_create(del_fn_t delfn, cmp_fn_t cmp_fn) void splaytree_destroy(splaytree_t* tree) { if (NULL != tree) { - //destroy_node(tree, tree->root); + destroy_node(tree, tree->root); (void)destroy_node; free(tree); } @@ -127,61 +103,56 @@ void splaytree_destroy(splaytree_t* tree) void splaytree_insert(splaytree_t* tree, uintptr_t key, void* value) { - (void)next_node; if (tree->root == NULL) { - tree->root = create_node(value); + tree->root = create_node(value, NULL, NULL); } else { /* Splay the closest node in value to the root */ - puts("before splay: "); - print_tree(tree->root); - puts(""); - /* Splay the new node to the top of the tree */ splay(tree, key); - puts("after splay: "); - print_tree(tree->root); - puts(""); - /* Compare the key to the new root */ - int cmp = tree->compare(key, tree->root->value); + node_t* root = tree->root; + int cmp = tree->compare(key, root->value); if (cmp < 0) { - node_t* newroot = create_node(value); - printf("newroot1: %lu\n", (uintptr_t)newroot->value); - newroot->left = tree->root->left; - newroot->right = tree->root; - tree->root->left = NULL; - tree->root = newroot; + node_t* newroot = create_node(value, root->left, root); + tree->root->left = NULL; + tree->root = newroot; } else if (cmp > 0) { - node_t* newroot = create_node(value); - newroot->right = tree->root->right; - newroot->left = tree->root; - printf("newroot2: %lu\n", (uintptr_t)newroot->value); - tree->root->right = NULL; - printf("newroot2: %lu\n", (uintptr_t)newroot->value); - tree->root = newroot; + node_t* newroot = create_node(value, root, root->right); + root->right = NULL; + tree->root = newroot; } else { /* do nothing, item already present */ } - printf("values: %lu %lu\n", (uintptr_t)value, (uintptr_t)(tree->root->value)); } } void* splaytree_lookup(splaytree_t* tree, uintptr_t key) { - node_t* current = tree->root; - while (current != NULL) { - int cmp_val = tree->compare(key, current->value); - if (cmp_val == 0) - return current->value; - else if (cmp_val < 0) - current = current->left; - else - current = current->right; + if (tree->root != NULL) { + splay(tree, key); + if (0 == tree->compare(key, tree->root->value)) + return tree->root->value; } return NULL; } void* splaytree_delete(splaytree_t* tree, uintptr_t key) { - (void)tree; - (void)key; + void* value = NULL; + if (tree->root != NULL) { + splay(tree, key); + if (0 == tree->compare(key, tree->root->value)) { + node_t* deadite = tree->root; + if (tree->root->left == NULL) { + tree->root = deadite->right; + } else { + tree->root = deadite->left; + splay(tree, key); + tree->root->right = deadite->right; + } + /* Return the value and kill the old root */ + value = deadite->value; + memset(deadite, 0x00, sizeof(node_t)); + destroy_node(tree, deadite); + } + } return NULL; } diff --git a/tests/test_heap.c b/tests/test_heap.c index 4667639..350a7ee 100644 --- a/tests/test_heap.c +++ b/tests/test_heap.c @@ -42,11 +42,9 @@ TEST_SUITE(Heap) { } TEST(Verify_Allocate_should_allocate_a_large_block_if_the_number_of_slots_is_greater_than_the_max) { - CHECK(false); - //heap_t* heap = heap_create(); - //CHECK(NULL != heap_allocate(heap, 65)); - //CHECK(heap->blocks != NULL); - //CHECK(heap->blocks->next == NULL); - //heap_destroy(heap); + heap_t* heap = heap_create(); + CHECK(NULL != heap_allocate(heap, 65)); + CHECK(NULL != heap->blocks->root->value); + heap_destroy(heap); } } diff --git a/tests/test_splaytree.c b/tests/test_splaytree.c index ca2b5df..d8dc239 100644 --- a/tests/test_splaytree.c +++ b/tests/test_splaytree.c @@ -23,30 +23,29 @@ TEST_SUITE(SplayTree) { /* Verify: splaytree_insert *************************************************************************/ -// TEST(Verify_Insert_will_insert_into_an_empty_tree) -// { -// splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); -// splaytree_insert(tree, 42, (void*)42); -// CHECK((void*)42 == tree->root->value); -// splaytree_destroy(tree); -// } -// -// TEST(Verify_Insert_will_insert_to_the_left_of_root_when_less_than) -// { -// splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); -// splaytree_insert(tree, 42, (void*)42); -// splaytree_insert(tree, 41, (void*)41); -// CHECK((void*)41 == tree->root->value); -// CHECK((void*)42 == tree->root->right->value); -// splaytree_destroy(tree); -// } + TEST(Verify_Insert_will_insert_into_an_empty_tree) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + CHECK((void*)42 == tree->root->value); + splaytree_destroy(tree); + } + + TEST(Verify_Insert_will_insert_to_the_left_of_root_when_less_than) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + splaytree_insert(tree, 41, (void*)41); + CHECK((void*)41 == tree->root->value); + CHECK((void*)42 == tree->root->right->value); + splaytree_destroy(tree); + } TEST(Verify_Insert_will_insert_to_the_right_of_root_when_greater_than) { splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); splaytree_insert(tree, 42, (void*)42); splaytree_insert(tree, 43, (void*)43); - printf("root->value: %p\n", tree->root->value); CHECK((void*)43 == tree->root->value); CHECK((void*)42 == tree->root->left->value); splaytree_destroy(tree); @@ -54,46 +53,97 @@ TEST_SUITE(SplayTree) { /* Verify: splaytree_lookup *************************************************************************/ -// TEST(Verify_Lookup_will_find_the_item_at_the_root) -// { -// splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); -// splaytree_insert(tree, 42, (void*)42); -// CHECK((void*)42 == splaytree_lookup(tree, 42)); -// splaytree_destroy(tree); -// } -// -// TEST(Verify_Lookup_will_find_the_item_left_of_root_when_less_than) -// { -// splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); -// splaytree_insert(tree, 42, (void*)42); -// splaytree_insert(tree, 41, (void*)41); -// CHECK((void*)41 == splaytree_lookup(tree, 41)); -// splaytree_destroy(tree); -// } -// -// TEST(Verify_Lookup_will_find_the_item_right_of_root_when_greater_than) -// { -// splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); -// splaytree_insert(tree, 42, (void*)42); -// splaytree_insert(tree, 43, (void*)43); -// CHECK((void*)43 == splaytree_lookup(tree, 43)); -// splaytree_destroy(tree); -// } -// -// /* Verify: splaytree_delete -// *************************************************************************/ -// TEST(Verify_Delete_will_delete_the_item_at_the_root) -// { -// CHECK(false); -// } -// -// TEST(Verify_Delete_will_delete_the_item_left_of_root_when_less_than) -// { -// CHECK(false); -// } -// -// TEST(Verify_Delete_will_delete_the_item_right_of_root_when_greater_than) -// { -// CHECK(false); -// } + TEST(Verify_Lookup_will_find_the_item_at_the_root) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + CHECK((void*)42 == splaytree_lookup(tree, 42)); + splaytree_destroy(tree); + } + + TEST(Verify_Lookup_will_find_the_item_left_of_root_when_less_than) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + splaytree_insert(tree, 41, (void*)41); + CHECK((void*)41 == splaytree_lookup(tree, 41)); + splaytree_destroy(tree); + } + + TEST(Verify_Lookup_will_find_the_item_right_of_root_when_greater_than) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + splaytree_insert(tree, 43, (void*)43); + CHECK((void*)43 == splaytree_lookup(tree, 43)); + splaytree_destroy(tree); + } + + /* Verify: splaytree_delete + *************************************************************************/ + TEST(Verify_Delete_will_delete_the_item_at_the_root) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + splaytree_delete(tree, 42); + CHECK(tree->root == NULL); + splaytree_destroy(tree); + } + + TEST(Verify_Delete_will_delete_the_smallest_item) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + splaytree_insert(tree, 43, (void*)43); + splaytree_delete(tree, 42); + CHECK(tree->root != NULL); + CHECK(tree->root->value == (void*)43); + splaytree_destroy(tree); + } + + TEST(Verify_Delete_will_delete_the_largest_item) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 42, (void*)42); + splaytree_insert(tree, 43, (void*)43); + splaytree_delete(tree, 43); + CHECK(tree->root != NULL); + CHECK(tree->root->value == (void*)42); + splaytree_destroy(tree); + } + + TEST(Verify_Delete_will_delete_the_item_to_the_left_of_root) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 41, (void*)41); + splaytree_insert(tree, 42, (void*)42); + splaytree_insert(tree, 43, (void*)43); + splaytree_delete(tree, 41); + CHECK(tree->root != NULL); + CHECK(tree->root->value == (void*)42); + splaytree_destroy(tree); + } + + TEST(Verify_Delete_will_delete_an_item_from_a_tree_with_depth_3) + { + splaytree_t* tree = splaytree_create((del_fn_t)del_int, (cmp_fn_t)cmp_int); + splaytree_insert(tree, 40, (void*)40); + splaytree_insert(tree, 41, (void*)41); + splaytree_insert(tree, 43, (void*)43); + splaytree_insert(tree, 44, (void*)44); + splaytree_insert(tree, 42, (void*)42); + splaytree_delete(tree, 42); + CHECK(tree->root != NULL); + CHECK(tree->root->value == (void*)41); + CHECK(tree->root->left != NULL); + CHECK(tree->root->left->value == (void*)40); + CHECK(tree->root->left->left == NULL); + CHECK(tree->root->left->right == NULL); + CHECK(tree->root->right != NULL); + CHECK(tree->root->right->value == (void*)43); + CHECK(tree->root->right->right != NULL); + CHECK(tree->root->right->right->value == (void*)44); + CHECK(tree->root->right->left == NULL); + splaytree_destroy(tree); + } }