Doble-Spiel/bintree.c

133 lines
3.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include "stack.h"
#include "bintree.h"
//Komplexität 𝑂() mit = Höhe des Baums ??
//fügt einen kopierten Datensatz in einen binären Suchbaum ein und meldet optional Duplikate.
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
{
if (root == NULL)
{
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
if (newNode == NULL)
return NULL;
newNode->data = malloc(dataSize);
if (newNode->data == NULL)
{
free(newNode);
return NULL;
}
memcpy(newNode->data, data, dataSize);
newNode->left = NULL;
newNode->right = NULL;
if (isDuplicate != NULL) *isDuplicate = 0;
return newNode;
}
int comparison = compareFct(data, root->data);
if (comparison == 0)
{
if (isDuplicate != NULL) *isDuplicate = 1;
return root;
}
else if (comparison < 0)
{
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
}
else
{
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
}
return root;
}
// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction.
// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
// push the top node and push all its left nodes.
//liefert nacheinander die Elemente in aufsteigender Reihenfolge (Inorder) (also wie sortiert) und merkt sich den Zustand zwischen Aufrufen mit einem Stack.
//Übergabe eines root initialisiert oder startet neu; root == NULL setzt die Iteration fort.
void *nextTreeData(TreeNode *root)
{
/* static iterator state using stack.c */
static StackNode *stack = NULL;
static TreeNode *currentRoot = NULL;
/* helper: push node and all left descendants */
void push_lefts(TreeNode *n)
{
while (n != NULL)
{
stack = push(stack, (void *)n);
n = n->left;
}
}
/* If a new root is provided and differs from current, or explicit restart with same root, reset iterator */
if (root != NULL && root != currentRoot)
{
clearStack(stack);
stack = NULL;
currentRoot = root;
push_lefts(root);
}
else if (root != NULL && root == currentRoot)
{
/* explicit restart with same root */
clearStack(stack);
stack = NULL;
push_lefts(root);
}
/* if root == NULL: continue with existing stack */
/* nothing left */
if (stack == NULL)
{
currentRoot = NULL;
return NULL;
}
/* pop top */
TreeNode *node = (TreeNode *)top(stack);
stack = pop(stack);
void *result = node->data;
/* if right child exists, push it and all its lefts */
if (node->right != NULL)
{
push_lefts(node->right);
}
return result;
}
// Gibnt alle Knoten und ihre daten frei.
void clearTree(TreeNode *root)
{
if (root == NULL)
return;
clearTree(root->left);
clearTree(root->right);
if (root->data != NULL)
free(root->data);
free(root);
}
// Zählt rekursiv die anzahl an knoten ab *root.
unsigned int treeSize(const TreeNode *root)
{
if (root == NULL)
return 0u;
return 1u + treeSize(root->left) + treeSize(root->right);
}