diff --git a/bintree.c b/bintree.c index 0e7be3a..c2b1c60 100644 --- a/bintree.c +++ b/bintree.c @@ -67,9 +67,68 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc // 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. +// Wir brauchen eine statische Variable, die überdauernd existiert +// (Alternativ kann man diese auch global ausserhalb definieren) +static Stack *iteratorStack = NULL; + void *nextTreeData(TreeNode *root) { + // --- FALL 1: Initialisierung (Neuer Baum wird übergeben) --- + if (root != NULL) + { + // Falls noch ein alter Stack da ist: Aufräumen! + // (Hängt von deiner stack.h ab, ob es clearStack oder ähnlich gibt) + if (iteratorStack != NULL) { + clearStack(iteratorStack); // oder freeStack, je nach Implementierung + iteratorStack = NULL; // Sicherstellen, dass er leer ist + } + + // Neuen Stack erstellen (falls nötig) + // Angenommen, du hast eine Funktion wie createStack() oder initStack() + if (iteratorStack == NULL) { + iteratorStack = createStack(); // oder wie deine Init-Funktion heißt + } + // Jetzt: "Push root and all left nodes" + TreeNode *currentNode = root; + while (currentNode != NULL) + { + push(iteratorStack, currentNode); // Achtung: Funktionsname aus stack.h prüfen + currentNode = currentNode->left; + } + + // Bei strtok gibt der erste Aufruf oft schon das erste Element zurück. + // Wir fallen also einfach in den Code unten rein (kein return hier). + } + + // --- FALL 2: Fortsetzung (root ist NULL) --- + // Wenn der Stack leer ist, sind wir fertig mit dem Baum + if (iteratorStack == NULL || stackIsEmpty(iteratorStack)) // Name aus stack.h prüfen + { + return NULL; + } + + // 1. Nimm das oberste Element (das ist "dran") + TreeNode *nodeToReturn = pop(iteratorStack); // Name aus stack.h prüfen + + // Daten sichern, bevor wir weitermachen + void *data = nodeToReturn->data; + + // 2. Vorbereiten für das NÄCHSTE Mal: + // Wenn wir rechts abbiegen können, tun wir das. + // Die Regel ist: Einmal rechts, dann immer links runter. + if (nodeToReturn->right != NULL) + { + TreeNode *currentNode = nodeToReturn->right; + + while (currentNode != NULL) + { + push(iteratorStack, currentNode); + currentNode = currentNode->left; + } + } + + return data; } // Releases all memory resources (including data copies). diff --git a/stack.c b/stack.c index e3a90d4..b108195 100644 --- a/stack.c +++ b/stack.c @@ -8,26 +8,69 @@ * `clearStack`: gibt den gesamten Speicher frei. */ // Pushes data as pointer onto the stack. + +// Hilfsfunktion: Erstellt nur den "Container" (die Node) +static StackNode *createStackNode(void *data) +{ + // 1. Container reservieren + StackNode *newNode = calloc(1, sizeof(StackNode)); + if(!newNode) return NULL; + + // 2. WICHTIG: Wir speichern nur den Zeiger (die Adresse)! + // Wir machen KEIN zweites malloc für die Daten. + // Der Stack "besitzt" die Daten nicht, er referenziert sie nur. + newNode->data = data; + + newNode->nextNode = NULL; + return newNode; +} + StackNode *push(StackNode *stack, void *data) { + // Neue Node erstellen + StackNode *newNode = createStackNode(data); + if (!newNode) { + return stack; // Fehlerfall: Stack bleibt unverändert (oder Fehlerbehandlung) + } + // Verkettung: Die neue Node zeigt auf den alten Kopf + newNode->nextNode = stack; + + // Die neue Node ist der neue Kopf (Rückgabewert) + return newNode; } // Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be // freed by caller.) StackNode *pop(StackNode *stack) { - + if(stack) + { + StackNode* tempNode = stack -> nextNode; + free(stack); + return tempNode; + } + return stack; } // Returns the data of the top element. void *top(StackNode *stack) { - + if(stack) + { + return stack ->data; + } + return NULL; } // Clears stack and releases all memory. void clearStack(StackNode *stack) { - + StackNode *temp = NULL; + while(stack) + { + temp = stack -> nextNode; + free(stack); + stack = temp; + } } \ No newline at end of file diff --git a/stack.h b/stack.h index f7d542d..4be3155 100644 --- a/stack.h +++ b/stack.h @@ -9,6 +9,12 @@ The latest element is taken from the stack. */ //TODO: passenden Datentyp als struct anlegen +typedef struct node +{ + void *data; + struct node* nextNode; +} StackNode; + // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data);