diff --git a/src/BinaryTree/BinaryTree.c b/src/BinaryTree/BinaryTree.c index 801aa3f..b044c97 100644 --- a/src/BinaryTree/BinaryTree.c +++ b/src/BinaryTree/BinaryTree.c @@ -13,8 +13,7 @@ typedef struct BinaryTreeWalker_s { enum BinaryTreeNodePosition position; } BinaryTreeWalker; -static size_t _TreeNodeSize(BinaryTree* tree) -{ +static size_t _TreeNodeSize(BinaryTree* tree) { return sizeof(BinaryTreeNode) + tree->value_size; } @@ -23,8 +22,7 @@ static inline size_t _DepthOf(BinaryTreeNode* node) return node == NULL ? 0 : node->depth; } -static BinaryTreeNode* _CreateNode(BinaryTree* tree, void* value) -{ +static BinaryTreeNode* _CreateNode(BinaryTree* tree, void* value) { BinaryTreeNode* node = Allocator_Allocate(tree->allocator, _TreeNodeSize(tree)); if (node != NULL) { memcpy(node->value, value, tree->value_size); @@ -36,8 +34,7 @@ static BinaryTreeNode* _CreateNode(BinaryTree* tree, void* value) return node; } -int BinaryTree_Create(BinaryTree* target, BinaryTreeComparator compare, void* xdata, size_t value_size, allocator_t* allocator) -{ +int BinaryTree_Create(BinaryTree* target, BinaryTreeComparator compare, void* xdata, size_t value_size, allocator_t* allocator) { target->root = NULL; target->compare = compare; target->xdata = xdata; @@ -50,8 +47,7 @@ int BinaryTree_Create(BinaryTree* target, BinaryTreeComparator compare, void* xd return EXIT_SUCCESS; } -static void _UpdateDepth(BinaryTreeNode* node) -{ +static void _UpdateDepth(BinaryTreeNode* node) { size_t depth_left = 0, depth_right = 0; if (node->left != NULL) { @@ -70,167 +66,58 @@ static void _UpdateDepth(BinaryTreeNode* node) node->depth += 1; } -static void _UpdateDepths(DynamicArray* parents) -{ +static void _UpdateDepths(DynamicArray* parents) { for (size_t i = parents->reserved - 1; i != SIZE_MAX; i--) { BinaryTreeWalker* walker = DynamicArray_GetPointer(parents, i); _UpdateDepth(walker->node); } } -static int _BinaryTree_ValueWalk(BinaryTree* tree, void* value) -{ +int _Insert(BinaryTree* tree, BinaryTreeNode* node) { BinaryTreeNode** parent = &tree->root; tree->walker_stack.reserved = 0; - while ((*parent) != NULL) { + if (*parent == NULL) { + *parent = node; + } + + while ((*parent) != node) { BinaryTreeWalker* walker; DynamicArray_AppendEmpty(&tree->walker_stack, (void**) &walker); // Can't be NULL because the size was just increased walker->node = *parent; - int comparison = tree->compare(value, (*parent)->value, tree->xdata); + int comparison = tree->compare(node->value, (*parent)->value, tree->xdata); if (comparison == 0) { // equal - walker->position = BINARYTREENODEPOSITION_SELF; - return EXIT_SUCCESS; + return EXIT_FAILURE; } else if (comparison < 0) { + // less than + if ((*parent)->left == NULL) { + (*parent)->left = node; + } + parent = &(*parent)->left; walker->position = BINARYTREENODEPOSITION_LEFT; } else { + // greater than + if ((*parent)->right == NULL) { + (*parent)->right = node; + } + parent = &(*parent)->right; walker->position = BINARYTREENODEPOSITION_RIGHT; } } - return ENOTFOUND; -} - -static int _BinaryTree_Insert(BinaryTree* tree, BinaryTreeNode* node) -{ - int walk_code = _BinaryTree_ValueWalk(tree, node->value); - - if (walk_code != ENOTFOUND) { - return EEXIST; - } - - BinaryTreeWalker* bottom_walker = DynamicArray_GetPointer(&tree->walker_stack, tree->walker_stack.reserved - 1); - if (bottom_walker == NULL) { - // root node is empty - tree->root = node; - return EXIT_SUCCESS; - } else { - switch (bottom_walker->position) { - case BINARYTREENODEPOSITION_SELF: - // unreachable code - return EXIT_FAILURE; - - case BINARYTREENODEPOSITION_LEFT: - bottom_walker->node->left = node; - break; - - case BINARYTREENODEPOSITION_RIGHT: - bottom_walker->node->right = node; - break; - } - } - - _UpdateDepths(&tree->walker_stack); + _UpdateDepths(&tree->walker_stack); _UpdateDepth(node); return EXIT_SUCCESS; } -static int _BinaryTree_DestroyNode(BinaryTree* tree, BinaryTreeNode* node) -{ - Allocator_Free(tree->allocator, node, sizeof(*node) + tree->value_size); - - return EXIT_SUCCESS; -} - -static BinaryTreeNode** _BinaryTreeNode_SmallestNodeLocation(BinaryTreeNode* node) -{ - if (node->left == NULL) { - return NULL; - } - - BinaryTreeNode** smallest_location = &node->left; - do { - smallest_location = &(*smallest_location)->left; - } while (smallest_location != NULL); - - return smallest_location; -} - -static int _BinaryTreeNode_UnlinkNode(BinaryTreeNode** nodep) -{ - size_t node_depth = _DepthOf(*nodep); - if (node_depth == 1) { - // leaf node without children - *nodep = NULL; - } else { - if ((*nodep)->left == NULL) { - // only right node active - *nodep = (*nodep)->right; - } else if ((*nodep)->right == NULL) { - // only left node active - *nodep = (*nodep)->left; - } else { - // both right and left node active - BinaryTreeNode** smallest_subnode = _BinaryTreeNode_SmallestNodeLocation(*nodep); - BinaryTreeNode* right_branch = (*nodep)->right; - *nodep = *smallest_subnode; - *smallest_subnode = (*smallest_subnode)->right; - (*nodep)->right = right_branch; - } - } - - return EXIT_SUCCESS; -} - -static int _BinaryTree_Remove(BinaryTree* self, void* value) -{ - int walk_code = _BinaryTree_ValueWalk(self, value); - - if (walk_code == ENOTFOUND) { - return ENOTFOUND; - } - - BinaryTreeWalker* bottom_walker = DynamicArray_GetPointer(&self->walker_stack, self->walker_stack.reserved - 2); - - BinaryTreeNode* preserved_pointer; - if (bottom_walker == NULL) { - // root node - preserved_pointer = self->root; - _BinaryTreeNode_UnlinkNode(&self->root); - self->walker_stack.reserved = 0; - } else { - BinaryTreeNode* parent_node = bottom_walker->node; - switch (bottom_walker->position) { - case BINARYTREENODEPOSITION_SELF: - return EXIT_FAILURE; - - case BINARYTREENODEPOSITION_LEFT: - preserved_pointer = parent_node->left; - _BinaryTreeNode_UnlinkNode(&parent_node->left); - break; - - case BINARYTREENODEPOSITION_RIGHT: - preserved_pointer = parent_node->right; - _BinaryTreeNode_UnlinkNode(&parent_node->right); - break; - } - - bottom_walker->position = BINARYTREENODEPOSITION_SELF; - } - - _BinaryTree_DestroyNode(self, preserved_pointer); - - return EXIT_SUCCESS; -} - int _GrowParentStack(BinaryTree* tree) { size_t depth = _DepthOf(tree->root); @@ -300,22 +187,8 @@ static void _Rebalance(BinaryTree* tree) break; case BINARYTREENODEPOSITION_SELF: - if (i == 0) { - nodep = &tree->root; - } else { - BinaryTreeWalker* parent_walker = DynamicArray_GetPointer( - &tree->walker_stack, - i - 1 - ); - if (parent_walker->position == BINARYTREENODEPOSITION_LEFT) { - nodep = &parent_walker->node->left; - } else { - // right, self is not allowed - nodep = &parent_walker->node->right; - } - } + // not gonna happen break; - } _RebalanceNode(nodep); @@ -325,8 +198,14 @@ static void _Rebalance(BinaryTree* tree) _RebalanceRoot(tree); } -int BinaryTree_Insert(BinaryTree* tree, void* value) +static int _BinaryTree_DestroyNode(BinaryTree* tree, BinaryTreeNode* node) { + Allocator_Free(tree->allocator, node, sizeof(*node) + tree->value_size); + + return EXIT_SUCCESS; +} + +int BinaryTree_Insert(BinaryTree* tree, void* value) { if (tree == NULL) return EDESTADDRREQ; if (value == NULL) return EINVAL; @@ -337,7 +216,7 @@ int BinaryTree_Insert(BinaryTree* tree, void* value) BinaryTreeNode* new_node = _CreateNode(tree, value); if (new_node == NULL) return ENOMEM; - if (_BinaryTree_Insert(tree, new_node)) { + if (_Insert(tree, new_node)) { _BinaryTree_DestroyNode(tree, new_node); return EXIT_FAILURE; } @@ -346,21 +225,6 @@ int BinaryTree_Insert(BinaryTree* tree, void* value) return EXIT_SUCCESS; } -int BinaryTree_Remove(BinaryTree* self, void* value) -{ - if (self == NULL) return EDESTADDRREQ; - if (value == NULL) return EINVAL; - - int remove_code = _BinaryTree_Remove(self, value); - if (remove_code) { - return remove_code; - } - - _Rebalance(self); - - return EXIT_SUCCESS; -} - int BinaryTree_ForEachPostOrder(BinaryTree* tree, BinaryTreeNodeFunction action, void* context) { tree->walker_stack.reserved = 0; diff --git a/src/BinaryTree/BinaryTree.h b/src/BinaryTree/BinaryTree.h index 0e084f5..72fbe18 100644 --- a/src/BinaryTree/BinaryTree.h +++ b/src/BinaryTree/BinaryTree.h @@ -13,7 +13,7 @@ typedef struct BinaryTreeNode_s { char value[]; } BinaryTreeNode; -typedef int (*BinaryTreeComparator) (void* self, void* other, void* xdata); +typedef int (*BinaryTreeComparator) (void* this, void* other, void* xdata); typedef struct BinaryTree_s { BinaryTreeNode* root; diff --git a/src/Scratchpad/Scratchpad.c b/src/Scratchpad/Scratchpad.c index 95b42a5..b905d59 100644 --- a/src/Scratchpad/Scratchpad.c +++ b/src/Scratchpad/Scratchpad.c @@ -108,8 +108,6 @@ int Scratchpad_Reclaim(Scratchpad* pad, void* pointer, size_t length) pad->reserved -= length; } - // TODO: Iterate into sub-scratchpads - return EXIT_SUCCESS; } diff --git a/src/errorcodes.h b/src/errorcodes.h index 3412182..916d534 100644 --- a/src/errorcodes.h +++ b/src/errorcodes.h @@ -42,11 +42,6 @@ #define ENOMEM 12 #endif -#ifndef EEXIST -// File/Resource exists already -#define EEXIST 17 -#endif - #ifndef ECANCELED // Not enough memory #define ECANCELED 132 diff --git a/tests/BinaryTree.test.c b/tests/BinaryTree.test.c index 0508efa..0356153 100644 --- a/tests/BinaryTree.test.c +++ b/tests/BinaryTree.test.c @@ -1,6 +1,5 @@ #include #include -#include #include "../src/BinaryTree/BinaryTree.h" @@ -36,15 +35,6 @@ void testLifetime(void) return; } -int _PrintDoubleNode(void* context, BinaryTreeNode* node) -{ - (void) context; - for (size_t i = 1; i != node->depth; i++) putchar('\t'); - printf("%.0f\n", *(double*) node->value); - - return EXIT_SUCCESS; -} - void testInsert(void) { allocator_t allocator; @@ -66,47 +56,22 @@ void testInsert(void) value = 3; assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - assert(*(double*) tree.root->left->value == value); value = 2; assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - assert(*(double*) tree.root->value == 3); - assert(*(double*) tree.root->left->value == 2); - assert(*(double*) tree.root->right->value == 5); value = 4; assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - assert(*(double*) tree.root->value == 3); - assert(*(double*) tree.root->left->value == 2); - assert(*(double*) tree.root->right->value == 5); - assert(*(double*) tree.root->right->left->value == 4); + value = 7; assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - assert(*(double*) tree.root->value == 3); - assert(*(double*) tree.root->left->value == 2); - assert(*(double*) tree.root->right->value == 5); - assert(*(double*) tree.root->right->left->value == 4); - assert(*(double*) tree.root->right->right->value == 7); value = 6; assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - assert(*(double*) tree.root->value == 5); - assert(*(double*) tree.root->left->value == 3); - assert(*(double*) tree.root->right->value == 7); - assert(*(double*) tree.root->right->left->value == 6); - assert(*(double*) tree.root->left->left->value == 2); - assert(*(double*) tree.root->left->right->value == 4); value = 8; assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - assert(*(double*) tree.root->value == 5); - assert(*(double*) tree.root->left->value == 3); - assert(*(double*) tree.root->right->value == 7); - assert(*(double*) tree.root->right->left->value == 6); - assert(*(double*) tree.root->right->right->value == 8); - assert(*(double*) tree.root->left->left->value == 2); - assert(*(double*) tree.root->left->right->value == 4); BinaryTree_Destroy(&tree); @@ -115,46 +80,6 @@ void testInsert(void) return; } -void testRemoval(void) -{ - allocator_t allocator; - Allocator_CreateSystemAllocator(&allocator); - BinaryTree tree; - - assert(EXIT_SUCCESS == BinaryTree_Create( - &tree, - (BinaryTreeComparator) doublecomparator, - (void*) 0xDEADBEEF, - sizeof(double), - &allocator) - ); - - double value = 5; - - assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - assert(tree.root != NULL); - - value = 3; - assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - - value = 2; - assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - - value = 4; - assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - - value = 5; - assert(EXIT_FAILURE == BinaryTree_Insert(&tree, &value)); - - assert(EXIT_SUCCESS == BinaryTree_Remove(&tree, &value)); - assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - - BinaryTree_Destroy(&tree); - assert(allocator.reserved == 0); - - return; -} - void testEqual(void) { allocator_t allocator; @@ -192,36 +117,10 @@ void testEqual(void) return; } -void testMany(void) -{ - allocator_t allocator; - Allocator_CreateSystemAllocator(&allocator); - BinaryTree tree; - - assert(EXIT_SUCCESS == BinaryTree_Create( - &tree, - (BinaryTreeComparator) doublecomparator, - (void*) 0xDEADBEEF, - sizeof(double), - &allocator) - ); - - for (double value = 0; value < 300; value++) { - assert(EXIT_SUCCESS == BinaryTree_Insert(&tree, &value)); - } - - BinaryTree_Destroy(&tree); - assert(allocator.reserved == 0); - - return; -} - int main() { testLifetime(); testInsert(); testEqual(); - testMany(); - testRemoval(); return 0; }