Fixed the sigsegv bug in binary tree

This commit is contained in:
VegOwOtenks 2024-10-13 22:05:41 +02:00
parent 88e4385c5f
commit 7c74b68d75
2 changed files with 45 additions and 11 deletions

View file

@ -150,18 +150,18 @@ static int _BinaryTree_DestroyNode(BinaryTree* tree, BinaryTreeNode* node)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static BinaryTreeNode** _BinaryTreeNode_SmallestNodeLocation(BinaryTreeNode* node) static BinaryTreeNode* _BinaryTreeNode_SmallestNodeParent(BinaryTreeNode* node)
{ {
if (node->left == NULL) { if (node->left == NULL) {
return NULL; return NULL;
} }
BinaryTreeNode** smallest_location = &node->left; BinaryTreeNode* parent = node;
do { while (parent->left != NULL && (parent->left->left != NULL)) {
smallest_location = &(*smallest_location)->left; parent = parent->left;
} while (smallest_location != NULL); }
return smallest_location; return parent;
} }
static int _BinaryTreeNode_UnlinkNode(BinaryTreeNode** nodep) static int _BinaryTreeNode_UnlinkNode(BinaryTreeNode** nodep)
@ -179,11 +179,15 @@ static int _BinaryTreeNode_UnlinkNode(BinaryTreeNode** nodep)
*nodep = (*nodep)->left; *nodep = (*nodep)->left;
} else { } else {
// both right and left node active // both right and left node active
BinaryTreeNode** smallest_subnode = _BinaryTreeNode_SmallestNodeLocation(*nodep); BinaryTreeNode* smallest_parent = _BinaryTreeNode_SmallestNodeParent(*nodep);
BinaryTreeNode* right_branch = (*nodep)->right; BinaryTreeNode* smallest_node = smallest_parent->left;
*nodep = *smallest_subnode;
*smallest_subnode = (*smallest_subnode)->right; smallest_parent->left = smallest_node->right;
(*nodep)->right = right_branch; smallest_node->right = (*nodep)->right;
smallest_node->left = (*nodep)->left;
*nodep = smallest_node;
_BinaryTreeNode_UpdateDepth(smallest_parent);
} }
} }
@ -225,6 +229,7 @@ static int _BinaryTree_Remove(BinaryTree* self, void* value)
bottom_walker->position = BINARYTREENODEPOSITION_SELF; bottom_walker->position = BINARYTREENODEPOSITION_SELF;
} }
DynamicArray_Remove(&self->walker_stack, self->walker_stack.reserved - 1);
_BinaryTree_DestroyNode(self, preserved_pointer); _BinaryTree_DestroyNode(self, preserved_pointer);

View file

@ -216,6 +216,34 @@ void testMany(void)
return; return;
} }
void testRanges(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));
}
for (double value = 150; value <= 200; value++) {
assert(EXIT_SUCCESS == BinaryTree_Remove(&tree, &value));
}
BinaryTree_Destroy(&tree);
assert(allocator.reserved == 0);
return;
}
int main() int main()
{ {
testLifetime(); testLifetime();
@ -223,5 +251,6 @@ int main()
testEqual(); testEqual();
testMany(); testMany();
testRemoval(); testRemoval();
testRanges();
return 0; return 0;
} }