diff --git a/bintree.c b/bintree.c index 56601c2..5ac7291 100644 --- a/bintree.c +++ b/bintree.c @@ -8,6 +8,7 @@ * `treeSize`: zählt die Knoten im Baum (rekursiv), * `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */ +static StackNode *stack = NULL; TreeNode* createNode(const void *data, size_t dataSize) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); @@ -34,36 +35,31 @@ // 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 *newNode = createNode(data,dataSize); + if (root == NULL) - { if (isDuplicate!=NULL) { - *isDuplicate = 0; - } + { + TreeNode *newNode = createNode(data,dataSize); + if (isDuplicate) + *isDuplicate = 0; + return newNode; } - if (compareFct(root->data, newNode->data)==0) + if (compareFct(root->data, data)==0) { - if (isDuplicate==NULL) { - free(newNode); - root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); - } - else - { - free(newNode->data); - free(newNode); + if (isDuplicate != NULL) { *isDuplicate=1; return root; } + TreeNode *newNode = createNode(data,dataSize); + return newNode; } - else if (compareFct(root->data, newNode->data)>0) + else if (compareFct(root->data, data)>0) { - free(newNode); root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); } - else if (compareFct(root->data, newNode -> data)<0) + else if (compareFct(root->data, data)<0) { - free(newNode); root->right= addToTree(root->right, data, dataSize, compareFct, isDuplicate); } return root; @@ -75,6 +71,15 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc void *nextTreeData(TreeNode *root) { + if (root != NULL) { + clearStack(stack); + stack = NULL; + } + while (root != NULL) + { + stack = push(stack, root->data); + root = root->left; + } } // Releases all memory resources (including data copies). diff --git a/highscores.txt b/highscores.txt index dc3e92c..3bb0566 100644 --- a/highscores.txt +++ b/highscores.txt @@ -1,3 +1,5 @@ player_name;18989 +test;9905 player_name;4983 +highscores.txt;4979 player1;3999 diff --git a/makefile b/makefile index 1f15f75..db88541 100644 --- a/makefile +++ b/makefile @@ -35,15 +35,14 @@ $(program_obj_filesobj_files): %.o: %.c # -------------------------- # Unit Tests # -------------------------- -unitTests: - echo "needs to be implemented" - +stackTests: stack.o test_stack.c $(unity_strc) + $(CC) $(CFLAGS) $(LDFLAGS) -I$(unityfolder) $^ -o runStackTests # -------------------------- # Clean # -------------------------- clean: ifeq ($(OS),Windows_NT) - del /f *.o doble + del /f *.o doble doble_initial runStackTests else - rm -f *.o doble + rm -f *.o doble doble_initial runStackTests endif \ No newline at end of file diff --git a/numbers.c b/numbers.c index f59d9a2..2b2719f 100644 --- a/numbers.c +++ b/numbers.c @@ -10,13 +10,35 @@ * Sicherstellen, dass beim Befüllen keine Duplikate entstehen. * Duplizieren eines zufälligen Eintrags im Array. * in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */ +int compareFct(const void *a, const void *b) + { + return *(int*)a - *(int*)b; + } // 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 *createNumbers(unsigned int len) { + TreeNode *root = NULL; + unsigned int* numbers = malloc(len * sizeof(unsigned int)); + srand(time(NULL)); + while(treeSize(root)data = data; - - // 3. Den 'next'-Zeiger des neuen Knotens auf den aktuellen Stack-Top setzen - // Der neue Knoten zeigt nun auf das Element, das zuvor ganz oben war. - newNode->next = stack; - - // 4. Den neuen Knoten als neuen Stack-Top zurückgeben - // Er ist jetzt das oberste Element. - 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) { -// 1. Überprüfen, ob der Stack leer ist - if (stack == NULL) - { - // Wenn der Stack leer ist, gibt es nichts zu entfernen. - // Wir geben NULL zurück, da der Stack immer noch leer ist. - return NULL; - } - // 2. Einen Zeiger auf das aktuelle oberste Element speichern - // Dieses Element wollen wir entfernen und dessen Speicher freigeben. - StackNode *oldTop = stack; - - // 3. Den Stack-Zeiger auf das nächste Element im Stack setzen - // Das Element, das unter dem alten Top lag, wird jetzt zum neuen Top. - StackNode *newTop = stack->next; - - // 4. Den Speicher des alten obersten Elements freigeben - // Wichtig: Die Daten, auf die oldTop->data zeigt, werden hier NICHT freigegeben. - // Das muss, wie in der .h-Datei beschrieben, vom Aufrufer erledigt werden, - // falls die Daten dynamisch alloziert wurden. - free(oldTop); - - // 5. Den neuen Stack-Top zurückgeben - return newTop; } // Returns the data of the top element. void *top(StackNode *stack) { - + if (stack == NULL) + { + return; + } + else + { + return stack->data; + } } // Clears stack and releases all memory. void clearStack(StackNode *stack) { - -} + StackNode *head = stack; + StackNode *current = head; + while(current) + { + free(current->data); + StackNode *nextNode = current->next; + free(current); + current = nextNode; + } + head = NULL; +} \ No newline at end of file diff --git a/stack.o b/stack.o new file mode 100644 index 0000000..13ef785 Binary files /dev/null and b/stack.o differ diff --git a/test_stack.c b/test_stack.c index b919500..ca865bb 100644 --- a/test_stack.c +++ b/test_stack.c @@ -48,7 +48,7 @@ void test_push_single_element() { stack = push(stack, data1); - assert_equals_ptr(data1, top(stack), "Top should be 10"); + assert_equals_ptr(data1, stack->data, "Top should be 10"); assert_equals_ptr(NULL, stack->next, "Next element should be NULL"); // Aufräumen @@ -67,7 +67,7 @@ void test_push_multiple_elements() { stack = push(stack, data2); // Stack: [20, 10] stack = push(stack, data3); // Stack: [30, 20, 10] - assert_equals_int(30, *(int*)top(stack), "Top should be 30"); + assert_equals_int(30, *(int*)stack->data, "Top should be 30"); assert_equals_int(20, *(int*)stack->next->data, "Second element should be 20"); assert_equals_int(10, *(int*)stack->next->next->data, "Third element should be 10"); assert_equals_ptr(NULL, stack->next->next->next, "Fourth element should be NULL"); @@ -91,14 +91,14 @@ void test_pop_single_element() { int *data1 = (int *)malloc(sizeof(int)); *data1 = 10; stack = push(stack, data1); // Stack: [10] - assert_equals_int(10, *(int*)top(stack), "Top should be 10 before pop"); + assert_equals_int(10, *(int*)stack->data, "Top should be 10 before pop"); // Daten freigeben, bevor der Knoten freigegeben wird free(top(stack)); // Freigabe von data1 stack = pop(stack); // Stack: [] assert_equals_ptr(NULL, stack, "Stack should be empty after popping last element"); - assert_equals_ptr(NULL, top(stack), "Top should be NULL after popping last element"); + assert_equals_ptr(NULL, stack->data, "Top should be NULL after popping last element"); } void test_pop_multiple_elements() {