diff --git a/bintree.c b/bintree.c index 1e34db0..d5d86ca 100644 --- a/bintree.c +++ b/bintree.c @@ -2,72 +2,47 @@ #include "stack.h" #include "bintree.h" -//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. */ - // 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 *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate) { - // Teil 1: Trivialfall (Einfügen des neuen Knotens) - if(root == NULL) + if (root == NULL) { - // Speicher für den Knoten selbst reservieren - TreeNode *newNode = (TreeNode*)malloc(sizeof(TreeNode)); + TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode)); if (newNode == NULL) - { - return NULL; // Fehler beim Allokieren - } + return NULL; - // Speicher für die Datenkopie reservieren newNode->data = malloc(dataSize); if (newNode->data == NULL) { free(newNode); - return NULL; // Fehler beim Allokieren + return NULL; } - // Daten kopieren memcpy(newNode->data, data, dataSize); - - // Initialisieren newNode->left = NULL; newNode->right = NULL; - // Flag setzen und Knoten zurückgeben if (isDuplicate != NULL) *isDuplicate = 0; return newNode; } - // Teil 2: Rekursiver Fall (Vergleich) int comparison = compareFct(data, root->data); if (comparison == 0) { - // Duplikat gefunden if (isDuplicate != NULL) *isDuplicate = 1; - // Duplikate werden akzeptiert, wenn isDuplicate == NULL (siehe bintree.h) - // Da wir aber in createNumbers Duplikate vermeiden wollen, geben wir hier einfach root zurück. - - // Wenn Duplikate erlaubt sind, könntest du hier einen zweiten Knoten einfügen, - // aber standardmäßig überspringen wir Duplikate, wenn isDuplicate gesetzt ist. return root; } else if (comparison < 0) { - // Wert ist kleiner -> gehe nach links root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); } - else // comparison > 0 + else { - // Wert ist größer -> gehe nach rechts root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate); } - // 3. Wenn die Rekursion zurückkehrt, wird der aktuelle root-Pointer zurückgegeben. return root; } @@ -76,81 +51,53 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc // push the top node and push all its left nodes. void *nextTreeData(TreeNode *root) { -/* static iterator state */ - static TreeNode **stack = NULL; - static int top = -1; - static int capacity = 0; + /* static iterator state using stack.c */ + static StackNode *stack = NULL; static TreeNode *currentRoot = NULL; - /* helper: ensure capacity */ - if (capacity == 0) { - capacity = 16; - stack = (TreeNode**)malloc(capacity * sizeof(TreeNode*)); - if (stack == NULL) { capacity = 0; return NULL; } - } - - /* helper: push one node */ - #define PUSH_NODE(n) do { \ - if (top + 1 >= capacity) { \ - int newcap = capacity * 2; \ - TreeNode **tmp = (TreeNode**)realloc(stack, newcap * sizeof(TreeNode*)); \ - if (tmp == NULL) { /* allocation failed, keep old stack */ break; } \ - stack = tmp; capacity = newcap; \ - } \ - stack[++top] = (n); \ - } while(0) - /* helper: push node and all left descendants */ - void push_lefts(TreeNode *n) { - while (n != NULL) { - PUSH_NODE(n); + 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, reset iterator */ - if (root != NULL && root != currentRoot) { - free(stack); + /* 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; - top = -1; - capacity = 0; currentRoot = root; - - /* reinitialize stack */ - capacity = 16; - stack = (TreeNode**)malloc(capacity * sizeof(TreeNode*)); - if (stack == NULL) { capacity = 0; return NULL; } - top = -1; push_lefts(root); - } else if (root != NULL && root == currentRoot) { - /* explicit restart with same root: reset and push again */ - free(stack); + } + else if (root != NULL && root == currentRoot) + { + /* explicit restart with same root */ + clearStack(stack); stack = NULL; - top = -1; - capacity = 0; - capacity = 16; - stack = (TreeNode**)malloc(capacity * sizeof(TreeNode*)); - if (stack == NULL) { capacity = 0; return NULL; } - top = -1; push_lefts(root); } /* if root == NULL: continue with existing stack */ /* nothing left */ - if (top < 0) { - free(stack); - stack = NULL; - capacity = 0; + if (stack == NULL) + { currentRoot = NULL; return NULL; } /* pop top */ - TreeNode *node = stack[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) { + if (node->right != NULL) + { push_lefts(node->right); } @@ -160,38 +107,23 @@ void *nextTreeData(TreeNode *root) // Releases all memory resources (including data copies). void clearTree(TreeNode *root) { - // 1. Basis-Fall: Wenn der Knoten NULL ist, beende if (root == NULL) - { return; - } - // 2. Rekursiver Schritt (gehe in die Tiefe) - - // Gib den linken Teilbaum frei clearTree(root->left); - - // Gib den rechten Teilbaum frei clearTree(root->right); - // 3. Aktion: Gebe die Ressourcen dieses Knotens frei - - // Zuerst die dynamisch kopierten Daten freigeben (siehe addToTree) if (root->data != NULL) - { - free(root->data); // Speicher für die Zahl freigeben - } + free(root->data); - // Dann den Knoten selbst freigeben free(root); } // Returns the number of entries in the tree given by root. unsigned int treeSize(const TreeNode *root) { - if (root == NULL) { //0 for end - return 0; - } - return 1u + treeSize(root->left) + treeSize(root->right); //using 1u to insure unsigned - //recursively adds entries in the tree after root to left and right -} \ No newline at end of file + if (root == NULL) + return 0u; + + return 1u + treeSize(root->left) + treeSize(root->right); +} diff --git a/makefile b/makefile index f92d187..d397220 100644 --- a/makefile +++ b/makefile @@ -32,6 +32,8 @@ doble : main.o $(program_obj_files) $(program_obj_filesobj_files): %.o: %.c $(CC) -c $(FLAGS) $^ -o $@ +#Ab hier redundant ------------------- + main.o: main.c $(CC) -c $(FLAGS) main.c