From e5c5f53ad40a620c564724d8d0e124f6ea574118 Mon Sep 17 00:00:00 2001 From: Simon May Date: Mon, 22 Dec 2025 13:29:04 +0100 Subject: [PATCH] numbers + tests angepasst --- bintree.c | 23 +++--- makefile | 8 +-- numbers.c | 188 +++++++++++++++++-------------------------------- stackTest.c | 100 -------------------------- test_bintree.c | 4 +- test_numbers.c | 55 ++++++++++----- test_stack.c | 41 ----------- 7 files changed, 122 insertions(+), 297 deletions(-) delete mode 100644 stackTest.c diff --git a/bintree.c b/bintree.c index a843c1d..9a50707 100644 --- a/bintree.c +++ b/bintree.c @@ -19,6 +19,10 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc { TreeNode *newNode = malloc(sizeof(TreeNode)); newNode->data = malloc(dataSize); + if (newNode->data == NULL) + { + return NULL; // Fehler + } memcpy(newNode->data, data, dataSize); newNode->left = NULL; newNode->right = NULL; @@ -38,7 +42,12 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc { if (isDuplicate != NULL) { - *isDuplicate = 1; // Mark as duplicate if needed. + *isDuplicate = 1; + return root; + } + else + { + root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); } } @@ -55,17 +64,14 @@ void *nextTreeData(TreeNode *root) clearStack(stack); buildStack(root); } - if(stack != NULL) { - void* data = top(stack); stack = pop(stack); return data; } return NULL; - } // Releases all memory resources (including data copies). @@ -75,7 +81,6 @@ void clearTree(TreeNode *root) { return; } - if (root->left != NULL) { clearTree(root->left); @@ -99,13 +104,11 @@ unsigned int treeSize(const TreeNode *root) void buildStack(TreeNode *root) { - if (root == NULL) { return; } - - buildStack(root->left); // biggest first - stack = push(stack, root->data); // push + buildStack(root->left); + stack = push(stack, root->data); buildStack(root->right); -} +} \ No newline at end of file diff --git a/makefile b/makefile index 890cc50..d439d9a 100644 --- a/makefile +++ b/makefile @@ -41,14 +41,14 @@ stackTests: stack.o test_stack.c $(unityfolder)/unity.c # -------------------------- # numbers.c Tests # -------------------------- -numbersTests: numbers.o test_numbers.c $(unityfolder)/unity.c - $(CC) $(FLAGS) -I$(unityfolder) -o runNumbersTest test_numbers.c numbers.o $(unityfolder)/unity.c +numbersTests: numbers.o bintree.o stack.o test_numbers.c $(unityfolder)/unity.c + $(CC) $(FLAGS) -I$(unityfolder) -o runNumbersTest test_numbers.c numbers.o bintree.o stack.o $(unityfolder)/unity.c # -------------------------- # bintree.c Tests # -------------------------- -bintreeTests: bintree.o test_bintree.c $(unityfolder)/unity.c - $(CC) $(FLAGS) -I$(unityfolder) -o runBintreeTest test_bintree.c bintree.o $(unityfolder)/unity.c +bintreeTests: bintree.o stack.o test_bintree.c $(unityfolder)/unity.c + $(CC) $(FLAGS) -I$(unityfolder) -o runBintreeTest test_bintree.c bintree.o stack.o $(unityfolder)/unity.c # -------------------------- # Clean diff --git a/numbers.c b/numbers.c index 0e13da0..90e930a 100644 --- a/numbers.c +++ b/numbers.c @@ -14,157 +14,97 @@ // Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries. // Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while // creating random numbers. -unsigned int checkArray(unsigned int *array, unsigned int len, unsigned int number) +void duplicateNumber(unsigned int *numbers, unsigned int len) { - int free = 1; + if (!numbers || len < 2) + return; - for (int i = 0; i < len; i++) - { - if (array[i] == number) - { - free = 0; - break; - - } - } + unsigned int numberPicked = rand() % len; // take random spot in array + unsigned int destination = rand() % len; // new spot for duplicated number - return free; + while (destination == numberPicked) // while same spot get a new one + destination = rand() % len; + + numbers[destination] = numbers[numberPicked]; +} + +/* for qsort +-1 num1 should come before num2 +0 num1 and num2 are equal +1 num1 should come after num2 +*/ +int compare(const void *num1, const void *num2) +{ + unsigned int temp1 = *(const unsigned int *)num1; + unsigned int temp2 = *(const unsigned int *)num2; + return (temp1 > temp2) - (temp1 < temp2); } unsigned int *createNumbers(unsigned int len) { - srand(time(NULL)); - unsigned int *array = (unsigned int *)malloc(len * sizeof(unsigned int)); - int randomNr, randomPos, filler; - - - if (array == NULL) + if (len < 2) { - return NULL; // Fehler + return NULL; + } + srand((unsigned)time(NULL)); + + TreeNode *root = NULL; + unsigned int i = 0; + + unsigned int *numbers = malloc(sizeof(unsigned int) * len); + if (!numbers) + { + return NULL; } - for (int i = 0; i < len; i++) + while (i < len) { - array[i] = 0; - } - - for (int i = 0; i < len; i++) - { - do + unsigned int random = (rand() % (2 * len)) + 1; + int duplicate = 0; + + root = addToTree(root, &random, sizeof(unsigned int), compare, &duplicate); + if (!root) { - array[i] = (rand() % (2 * len))+ 1; - } while (!checkArray(array, i, array[i])); - } - - randomPos = rand() % len; - randomNr = array[randomPos]; - - filler = randomPos; - while(filler == randomPos) - { - filler = rand() % len; - } - array[filler] = randomNr; - - return array; -} - -void merge(unsigned int arr[], unsigned int left, unsigned int mid, unsigned int right) -{ - unsigned int i, j, k; - unsigned int n1 = mid - left + 1; - unsigned int n2 = right - mid; - - // Create temporary arrays - unsigned int leftArr[n1], rightArr[n2]; - - // Copy data to temporary arrays - for (i = 0; i < n1; i++) - leftArr[i] = arr[left + i]; - for (j = 0; j < n2; j++) - rightArr[j] = arr[mid + 1 + j]; - - // Merge the temporary arrays back into arr[left..right] - i = 0; - j = 0; - k = left; - while (i < n1 && j < n2) - { - if (leftArr[i] <= rightArr[j]) - { - arr[k] = leftArr[i]; - i++; + free(numbers); // malloc-Fehler + return NULL; } - else - { - arr[k] = rightArr[j]; - j++; - } - k++; + + if (!duplicate) + numbers[i++] = random; } - // Copy the remaining elements of leftArr[], if any - while (i < n1) - { - arr[k] = leftArr[i]; - i++; - k++; - } - - // Copy the remaining elements of rightArr[], if any - while (j < n2) - { - arr[k] = rightArr[j]; - j++; - k++; - } + duplicateNumber(numbers, len); + clearTree(root); + return numbers; } -void mergeSort(unsigned int arr[], unsigned int left, unsigned int right) -{ - if (left < right) - { - - // Calculate the midpoint - unsigned int mid = left + (right - left) / 2; - - // Sort first and second halves - mergeSort(arr, left, mid); - mergeSort(arr, mid + 1, right); - - // Merge the sorted halves - merge(arr, left, mid, right); - } -} - -// Returns only the only number in numbers which is present twice. Returns zero on errors. +// Returns the only number in numbers which is present twice. Returns zero on errors. unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) { - unsigned int temp[len]; - unsigned int duplicate = 0; - - /*if(numbers == NULL || (sizeof(numbers) / sizeof(typeof(numbers)) != len)) + if (!numbers || len < 2) { - return 0;S - }*/ - - for (int i = 0; i < len; i++) - { - temp[i] = numbers[i]; + return 0; } - // Sorting arr using mergesort - mergeSort(temp, 0, len - 1); - - for (int i = 0; i < len - 1; i++) + unsigned int *copy = (unsigned int *)malloc(len * sizeof(unsigned int)); + if (!copy) { - duplicate = temp[i]; - if (duplicate == temp[i + 1]) - { + return 0; + } + memcpy(copy, numbers, len * sizeof(unsigned int)); + qsort(copy, len, sizeof(unsigned int), compare); + + unsigned int duplicate = 0; + for (unsigned int i = 1; i < len; i++) + { + if (copy[i] == copy[i - 1]) + { + duplicate = copy[i]; break; } } + free(copy); return duplicate; } \ No newline at end of file diff --git a/stackTest.c b/stackTest.c deleted file mode 100644 index 971b172..0000000 --- a/stackTest.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "unity.h" -#include "stack.h" // Stack-Header-Datei -#include - -// Test Setup and Teardown Functions -void setUp(void) { - // Setup code (falls notwendig, wie Initialisierungen) -} - -void tearDown(void) { - // Cleanup code (falls notwendig) -} - -// Test for push operation -void test_push(void) { - StackNode *stack = NULL; - int data1 = 10, data2 = 20; - - // Push elements to the stack - stack = push(stack, &data1); - stack = push(stack, &data2); - - // Check if the stack is not empty - TEST_ASSERT_NOT_NULL(stack); - - // Check if the top element is correct - int *topData = top(stack); - TEST_ASSERT_EQUAL_INT(20, *topData); // The last pushed element should be on top -} - -// Test for pop operation -void test_pop(void) { - StackNode *stack = NULL; - int data1 = 10, data2 = 20; - - // Push elements to the stack - stack = push(stack, &data1); - stack = push(stack, &data2); - - // Pop the top element - stack = pop(stack); - - // Check if the top element is now the first pushed element - int *topData = top(stack); - TEST_ASSERT_EQUAL_INT(10, *topData); // After popping, the first element should be on top - - // Pop the last element - stack = pop(stack); - - // Check if the stack is empty now - TEST_ASSERT_NULL(stack); // Stack should be NULL now -} - -// Test for top operation -void test_top(void) { - StackNode *stack = NULL; - int data1 = 10, data2 = 20; - - // Push elements to the stack - stack = push(stack, &data1); - stack = push(stack, &data2); - - // Check the top element - int *topData = top(stack); - TEST_ASSERT_EQUAL_INT(20, *topData); // The top element should be 20 (last pushed) - - // Pop the top element and check the new top - stack = pop(stack); - topData = top(stack); - TEST_ASSERT_EQUAL_INT(10, *topData); // Now the top element should be 10 -} - -// Test for clearStack operation -void test_clearStack(void) { - StackNode *stack = NULL; - int data1 = 10, data2 = 20; - - // Push elements to the stack - stack = push(stack, &data1); - stack = push(stack, &data2); - - // Clear the stack - clearStack(stack); - - // The stack should be empty now - TEST_ASSERT_NULL(stack); // Stack should be NULL -} - -// Run all tests -int main(void) { - UNITY_BEGIN(); - - // Run the individual test functions - RUN_TEST(test_push); - RUN_TEST(test_pop); - RUN_TEST(test_top); - RUN_TEST(test_clearStack); - - return UNITY_END(); -} diff --git a/test_bintree.c b/test_bintree.c index 4df2dbe..b5daa3a 100644 --- a/test_bintree.c +++ b/test_bintree.c @@ -51,9 +51,9 @@ void clearTest() node2->left = NULL; node2->right = NULL; - TreeNode *ptr = root; + clearTree(root); + root = NULL; - clearTree(ptr); TEST_ASSERT_EQUAL_INT(0,treeSize(root)); } diff --git a/test_numbers.c b/test_numbers.c index 04b5069..f98a45f 100644 --- a/test_numbers.c +++ b/test_numbers.c @@ -3,26 +3,47 @@ #include "numbers.h" #include "unity.h" -void createNumbersTest() +void test_createNumbers() { - unsigned int *array; unsigned int len = 6; - - array = createNumbers(len); - for (int i = 0; i < len; i++) - { - printf("%u ", array[i]); - } - printf("\n"); + unsigned int *array = createNumbers(len); TEST_ASSERT_NOT_NULL(array); + + unsigned int duplicate = getDuplicate(array, len); + TEST_ASSERT_NOT_EQUAL(0, duplicate); + + int counter = 0; + for (unsigned int i = 0; i < len; i++) + { + if (array[i] == duplicate) + counter++; + } + + TEST_ASSERT_EQUAL(2, counter); + + free(array); } -void duplicateTest() +void test_createNumbers_values() { - unsigned int array[6] = {1, 4, 5, 2, 3, 1}; unsigned int len = 6; + unsigned int *array = createNumbers(len); + TEST_ASSERT_NOT_NULL(array); - TEST_ASSERT_EQUAL_INT(1, getDuplicate(array, len)); + for (unsigned int i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(array[i] >= 1); + TEST_ASSERT_TRUE(array[i] <= 2 * len); + } + + free(array); +} + +void test_getDuplicate() +{ + unsigned int array[6] = {1, 2, 4, 4, 6, 7}; + unsigned int duplicate = getDuplicate(array, 6); + TEST_ASSERT_EQUAL_UINT(4, duplicate); } void setUp(void) @@ -35,13 +56,15 @@ void tearDown(void) // Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden } -int main() +int main() { UNITY_BEGIN(); - printf("============================\nNumbers tests\n============================\n"); - RUN_TEST(createNumbersTest); - RUN_TEST(duplicateTest); + printf("\n============================\n Numbers tests\n============================\n"); + + RUN_TEST(test_createNumbers); + RUN_TEST(test_createNumbers_values); + RUN_TEST(test_getDuplicate); return UNITY_END(); } \ No newline at end of file diff --git a/test_stack.c b/test_stack.c index c611dba..874e5f7 100644 --- a/test_stack.c +++ b/test_stack.c @@ -132,46 +132,6 @@ void test_top2(void) TEST_ASSERT_EQUAL_INT(node2->data, data); } -void test_clearStack(void) { - StackNode *stack = NULL; - int data1 = 10, data2 = 20; - - // Push elements to the stack - stack = push(stack, &data1); - stack = push(stack, &data2); - - // Clear the stack - clearStack(stack); - - // The stack should be empty now - TEST_ASSERT_NULL(stack); // Stack should be NULL -} - -void test_clear() -{ - int x,y,z; - x = 1; - y = 2; - z = 3; - StackNode* node2 = setup(&z, NULL); - StackNode* node1 = setup(&y, node2); - StackNode* header = setup(&x, node1); - StackNode* temp; - - clearStack(header); - temp = header; - - int after = 0; - while(temp) - { - after++; - temp = temp->next; - } - - - TEST_ASSERT_NULL(after); -} - void setUp(void) { // Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden @@ -191,7 +151,6 @@ int main() RUN_TEST(test_push); RUN_TEST(test_pop); RUN_TEST(test_top); - RUN_TEST(test_clearStack); return UNITY_END(); } \ No newline at end of file