#include "bintree.h" #include "stack.h" #include // TODO: binären Suchbaum implementieren /* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv), * `clearTree`: gibt den gesamten Baum frei (rekursiv), * `treeSize`: zählt die Knoten im Baum (rekursiv), * `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */ // typedef int (*CompareFctType)(const void *arg1, const void *arg2); // Adds a copy of data's pointer destination to the tree using compareFct for // ordering. Accepts duplicates if isDuplicate is NULL, otherwise ignores // duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). TreeNode *createTreeNode(const void *data, size_t dataSize) { TreeNode *node = malloc(sizeof(TreeNode)); // Speicher für neuen Knoten reservieren if (node == NULL) return NULL; // Abbrechen bei Fehler node->data = malloc(dataSize); // Speicher für Daten reservieren if (node->data == NULL) { free(node); return NULL; } memcpy(node->data, data, dataSize); // Standardfunktion string.h, kopiert // size bytes von data nach node->data, // daten dürfen sich nicht überschneiden // speichern der Daten in node->data node->left = NULL; // Kinder sind NULL node->right = NULL; return node; } TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate) { // isDuplicate initialisieren (auf 0 setzen), verhindert Änderung am Baum if (isDuplicate) { *isDuplicate = 0; } // bei 0: neuer Wert wurde eingefügt, bei 1: Wert war bereits im Baum // leerer Baum if (root == NULL) { return createTreeNode(data, dataSize); } // mit compareFct <0 links >0 rechts =0 Duplikat int compare = compareFct(data, root->data); if (compare < 0) { // Eintrag links root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); } else if (compare > 0) { // Eintrag rechts root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate); } else { // Duplikat // isDuplicate auf 1 setzen, keine Änderung am Baum if (isDuplicate) { *isDuplicate = 1; } } 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. void *nextTreeData(TreeNode *root) { static StackNode *stack = NULL; // static -> behält Wert bei mehreren Aufrufen // Neue Iteration starten if (root != NULL) { clearStack(&stack); // alte Stack-Inhalte werden gelöscht TreeNode *currentNode = root; while (currentNode != NULL) { // alle linken Knoten werden vom root an auf den Stack gelegt StackNode *oldStack = stack; StackNode *newStack = push(stack, currentNode); if (newStack == oldStack) return NULL; // push fehlgeschlagen stack = newStack; currentNode = currentNode->left; } } if (stack == NULL) return NULL; // wenn Stack leer ist sind keine Elemente mehr vorhanden, // Iteration beendet // oberster Knoten vom Stack TreeNode *node = top(stack); stack = pop(stack); // Rechten Teilbaum pushen TreeNode *currentNode = node->right; while (currentNode != NULL) { StackNode *oldStack = stack; StackNode *newStack = push(stack, currentNode); if (newStack == oldStack) return NULL; // push fehlgeschlagen stack = newStack; currentNode = currentNode->left; } return node->data; // Pointer auf Daten } // Releases all memory resources (including data copies). void clearTree(TreeNode **root) { // rekursive Funktion zum freigeben des // Speichers und Nullsetzen der Pointer if (root == NULL || *root == NULL) return; clearTree(&(*root)->left); // linken Teilbaum löschen clearTree(&(*root)->right); // rechten Teilbaum löschen free((*root)->data); // Daten freigeben (*root)->data = NULL; free(*root); // Knoten freigeben *root = NULL; // Zeiger auf NULL setzen } // 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); }