*/
#include "splaytree.h"
#include <stdlib.h>
-#include <stdio.h>
+#include <string.h>
-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);
}
}
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;
void splaytree_destroy(splaytree_t* tree)
{
if (NULL != tree) {
- //destroy_node(tree, tree->root);
+ destroy_node(tree, tree->root);
(void)destroy_node;
free(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;
}
/* 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);
/* 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);
+ }
}