diff --git a/bintree.c b/bintree.c index 5cf82a9..a9c8211 100644 --- a/bintree.c +++ b/bintree.c @@ -10,27 +10,98 @@ // 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) -{ +TreeNode *addToTree(TreeNode *root, + const void *data, + size_t dataSize, + CompareFctType compareFct, + int *isDuplicate) { + if (!root) { + // allocate new node + TreeNode *node = malloc(sizeof(TreeNode)); + if (!node) return NULL; + node->data = malloc(dataSize); + if (!node->data) { + free(node); + return NULL; + } + + memcpy(node->data, data, dataSize); + node->left = node->right = NULL; + + if (isDuplicate) *isDuplicate = 0; + return node; + } + + int cmp = compareFct(data, root->data); + + if (cmp == 0) { + // duplicate + if (isDuplicate) *isDuplicate = 1; + return root; // do not insert duplicate + } + + if (cmp < 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. void *nextTreeData(TreeNode *root) { + static StackNode *stack = NULL; + // New tree → reset stack and push left path + if (root != NULL) { + clearStack(stack); + stack = NULL; + + TreeNode *curr = root; + while (curr) { + stack = push(stack, curr); + curr = curr->left; + } + } + + // No tree / finished + if (!stack) return NULL; + + // Top node + TreeNode *node = top(stack); + stack = pop(stack); + + // After returning node, push its right subtree (all left nodes) + TreeNode *curr = node->right; + while (curr) { + stack = push(stack, curr); + curr = curr->left; + } + + return node->data; } // Releases all memory resources (including data copies). void clearTree(TreeNode *root) { + if (!root) return; + clearTree(root->left); + clearTree(root->right); + + free(root->data); + free(root); } + // Returns the number of entries in the tree given by root. unsigned int treeSize(const TreeNode *root) { - + if (!root) return 0; + return 1 + treeSize(root->left) + treeSize(root->right); } \ No newline at end of file diff --git a/numbers.c b/numbers.c index f59d9a2..66bc744 100644 --- a/numbers.c +++ b/numbers.c @@ -16,11 +16,75 @@ // creating random numbers. unsigned int *createNumbers(unsigned int len) { + if (len < 2) return NULL; + unsigned int *numbers = malloc(len * sizeof(unsigned int)); + if (!numbers) return NULL; + + srand((unsigned int)time(NULL)); + + TreeNode *root = NULL; + unsigned int maxValue = 2 * len; + + unsigned int uniqueCount = len - 1; // we generate len-1 unique values + unsigned int i = 0; + + // Fill len - 1 unique values using BST + while (i < uniqueCount) { + unsigned int r = (rand() % maxValue) + 1; + int isDup = 0; + + root = addToTree(root, &r, sizeof(unsigned int), compareUnsigned, &isDup); + + if (!isDup) { + numbers[i] = r; + i++; + } + } + + // Pick one number already in the list → duplicate it + unsigned int duplicateIndex = rand() % uniqueCount; + unsigned int duplicateValue = numbers[duplicateIndex]; + + numbers[len - 1] = duplicateValue; + + // Cleanup tree + clearTree(root); + + // Shuffle array for randomness + for (unsigned int j = 0; j < len; j++) { + unsigned int k = rand() % len; + unsigned int tmp = numbers[j]; + numbers[j] = numbers[k]; + numbers[k] = tmp; + } + + return numbers; } + // Returns only the only number in numbers which is present twice. Returns zero on errors. unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) { + if (!numbers || len < 2) return 0; -} \ No newline at end of file + // Make a copy because qsort modifies the array + unsigned int *copy = malloc(len * sizeof(unsigned int)); + if (!copy) return 0; + + memcpy(copy, numbers, len * sizeof(unsigned int)); + + qsort(copy, len, sizeof(unsigned int), compareUnsigned); + + // Check adjacent elements for equality + for (unsigned int i = 0; i < len - 1; i++) { + if (copy[i] == copy[i + 1]) { + unsigned int result = copy[i]; + free(copy); + return result; + } + } + + free(copy); + return 0; // no duplicate found (should not happen) +}