diff --git a/bintree.c b/bintree.c index b73a4c8..cd4571a 100644 --- a/bintree.c +++ b/bintree.c @@ -76,7 +76,85 @@ 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 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); + n = n->left; + } + } + + /* If a new root is provided and differs from current, reset iterator */ + if (root != NULL && root != currentRoot) { + free(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); + 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; + currentRoot = NULL; + return NULL; + } + + /* pop top */ + TreeNode *node = stack[top--]; + void *result = node->data; + + /* if right child exists, push it and all its lefts */ + if (node->right != NULL) { + push_lefts(node->right); + } + + return result; } // Releases all memory resources (including data copies).