A3_DobleSpiel/bintree.c
DESKTOP-0TGNH6T\alial ccd912be91 bintree and tests
2026-06-08 16:45:03 +02:00

144 lines
3.1 KiB
C

#include <stdlib.h>
#include <string.h>
#include "stack.h"
#include "bintree.h"
static TreeNode *createTreeNode(const void *data, size_t dataSize)
{
TreeNode *node = NULL;
if (data == NULL || dataSize == 0)
{
return NULL;
}
node = (TreeNode *)malloc(sizeof(TreeNode));
if (node == NULL)
{
return NULL;
}
node->data = malloc(dataSize);
if (node->data == NULL)
{
free(node);
return NULL;
}
memcpy(node->data, data, dataSize);
node->left = NULL;
node->right = NULL;
return node;
}
// Adds a copy of data's pointer destination to the tree using compareFct for ordering.
// If isDuplicate is NULL, duplicates are accepted. Otherwise duplicates are ignored and
// isDuplicate is set to 1. If a new value is inserted, isDuplicate is set to 0.
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
{
int compareResult = 0;
if (data == NULL || dataSize == 0 || compareFct == NULL)
{
return root;
}
if (root == NULL)
{
TreeNode *newNode = createTreeNode(data, dataSize);
if (newNode != NULL && isDuplicate != NULL)
{
*isDuplicate = 0;
}
return newNode;
}
compareResult = compareFct(data, root->data);
if (compareResult == 0 && isDuplicate != NULL)
{
*isDuplicate = 1;
return root;
}
if (compareResult < 0)
{
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
}
else
{
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
}
return root;
}
static StackNode *pushLeftPath(StackNode *stack, TreeNode *node)
{
while (node != NULL)
{
stack = push(stack, node);
node = node->left;
}
return stack;
}
// Iterates over the tree in sorted order. If root is not NULL, a new iteration starts.
// If root is NULL, the next element of the last tree is returned.
void *nextTreeData(TreeNode *root)
{
static StackNode *iteratorStack = NULL;
TreeNode *currentNode = NULL;
void *data = NULL;
if (root != NULL)
{
clearStack(iteratorStack);
iteratorStack = NULL;
iteratorStack = pushLeftPath(iteratorStack, root);
}
currentNode = (TreeNode *)top(iteratorStack);
if (currentNode == NULL)
{
clearStack(iteratorStack);
iteratorStack = NULL;
return NULL;
}
iteratorStack = pop(iteratorStack);
data = currentNode->data;
iteratorStack = pushLeftPath(iteratorStack, currentNode->right);
return data;
}
// Releases all memory resources, including the copied data in each tree node.
void clearTree(TreeNode *root)
{
if (root != NULL)
{
clearTree(root->left);
clearTree(root->right);
free(root->data);
free(root);
}
}
// Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root)
{
if (root == NULL)
{
return 0;
}
return 1 + treeSize(root->left) + treeSize(root->right);
}