generated from freudenreichan/info2Praktikum-DobleSpiel
144 lines
3.1 KiB
C
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);
|
|
} |