From d6a439f85a602d2d176358b6df5b8317b1d85a7f Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 19 Nov 2025 23:37:32 +0100 Subject: [PATCH 01/14] small changes makefile --- I2_Dobble/makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/I2_Dobble/makefile b/I2_Dobble/makefile index f2acc1f..328cc1a 100644 --- a/I2_Dobble/makefile +++ b/I2_Dobble/makefile @@ -50,7 +50,7 @@ numbersTest: numbers.o bintree.o numbersTest.o $($(unityfolder)/unity.c) # -------------------------- clean: ifeq ($(OS),Windows_NT) - del /f *.o doble runNumbersTest + del /f *.o doble runNumbersTest doble_initial else - rm -f *.o doble runNumbersTest + rm -f *.o doble runNumbersTest doble_initial endif \ No newline at end of file From 0c075ea18c7d1d806c2c9ec7fda53573041c0c37 Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 00:31:48 +0100 Subject: [PATCH 02/14] stackTest file added --- I2_Dobble/stackTest.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 I2_Dobble/stackTest.c diff --git a/I2_Dobble/stackTest.c b/I2_Dobble/stackTest.c new file mode 100644 index 0000000..d58dc45 --- /dev/null +++ b/I2_Dobble/stackTest.c @@ -0,0 +1,13 @@ +#include "stack.h" +#include "unity.h" +#include "unity_internals.h" + +void setUp(void) { } +void tearDown(void) { } + +int main() +{ + UNITY_BEGIN(); + + return UNITY_END(); +} \ No newline at end of file From cd13bbea4e2911ac69c263014d8603ce870de203 Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 00:32:10 +0100 Subject: [PATCH 03/14] bintreeTest file added --- I2_Dobble/bintreeTest.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 I2_Dobble/bintreeTest.c diff --git a/I2_Dobble/bintreeTest.c b/I2_Dobble/bintreeTest.c new file mode 100644 index 0000000..6642f9f --- /dev/null +++ b/I2_Dobble/bintreeTest.c @@ -0,0 +1,13 @@ +#include "bintree.h" +#include "unity.h" +#include "unity_internals.h" + +void setUp(void) { } +void tearDown(void) { } + +int main() +{ + UNITY_BEGIN(); + + return UNITY_END(); +} \ No newline at end of file From 12742b46fe3d211b575a4aba5e5f22d843294ad8 Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 00:32:30 +0100 Subject: [PATCH 04/14] small fix numbersTest --- I2_Dobble/numbersTest.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/I2_Dobble/numbersTest.c b/I2_Dobble/numbersTest.c index 4bca72d..feb7527 100644 --- a/I2_Dobble/numbersTest.c +++ b/I2_Dobble/numbersTest.c @@ -1,3 +1,4 @@ +#include #include "numbers.h" #include "unity.h" #include "unity_internals.h" @@ -75,6 +76,9 @@ void test_complete_function_of_numbers(void) free(arr); } +void setUp(void) { } +void tearDown(void) { } + int main(void) { UNITY_BEGIN(); From b0826ec05731a983ed11cf9082650b1b5f7f42e5 Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 00:32:57 +0100 Subject: [PATCH 05/14] stack completed --- I2_Dobble/stack.c | 23 +++++++++++++++++++++++ I2_Dobble/stack.h | 5 +++++ 2 files changed, 28 insertions(+) diff --git a/I2_Dobble/stack.c b/I2_Dobble/stack.c index e3a90d4..bdcec8e 100644 --- a/I2_Dobble/stack.c +++ b/I2_Dobble/stack.c @@ -10,24 +10,47 @@ // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data) { + StackNode *newNode = malloc(sizeof(StackNode)); + if (!newNode) + return stack; + + newNode->data = data; + newNode->next = stack; + 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 == NULL) + return NULL; + + StackNode *newTopElement = stack->next; + free(stack); + return newTopElement; } // Returns the data of the top element. void *top(StackNode *stack) { + if (!stack) + return NULL; + return stack->data; } // Clears stack and releases all memory. void clearStack(StackNode *stack) { + StackNode *current = stack; + while (current) + { + StackNode *next = current->next; + free(current); + current = next; + } } \ No newline at end of file diff --git a/I2_Dobble/stack.h b/I2_Dobble/stack.h index f7d542d..e88e8f0 100644 --- a/I2_Dobble/stack.h +++ b/I2_Dobble/stack.h @@ -8,6 +8,11 @@ The latest element is taken from the stack. */ #include //TODO: passenden Datentyp als struct anlegen +typedef struct stack +{ + void *data; + struct stack *next; +} StackNode; // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data); From 85b5c181a0282cc98a13cdaf32217c5064fc9932 Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 00:33:08 +0100 Subject: [PATCH 06/14] bintree added --- I2_Dobble/bintree.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/I2_Dobble/bintree.c b/I2_Dobble/bintree.c index 5cf82a9..ace0cb4 100644 --- a/I2_Dobble/bintree.c +++ b/I2_Dobble/bintree.c @@ -8,11 +8,51 @@ * `treeSize`: zählt die Knoten im Baum (rekursiv), * `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */ +static StackNode *iteratorStack = NULL; + // 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) { + if (root == NULL) + { + // Neue Node anlegen + TreeNode *newNode = malloc(sizeof(TreeNode)); + if (!newNode) return NULL; + newNode->data = malloc(dataSize); + if(!newNode->data) + { + free(newNode); + return NULL; + } + + memcpy(newNode->data, data, dataSize); + + newNode->left = NULL; + newNode->right = NULL; + + if (isDuplicate) + *isDuplicate = 0; + + return newNode; + } + + int cmp = compareFct(data, root->data); + + if (cmp == 0) + { + if (isDuplicate) + *isDuplicate = 1; + return root; // Einfügen verhindern + } + + 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. @@ -20,17 +60,58 @@ 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) { + // Neues Traversieren? + if (root != NULL) + { + clearStack(iteratorStack); + iteratorStack = NULL; + // Root + alle linken Nachfolger pushen + TreeNode *current = root; + while (current != NULL) + { + iteratorStack = push(iteratorStack, current); + current = current->left; + } + } + + // Wenn Stack leer → fertig + if (iteratorStack == NULL) + return NULL; + + // Top-Node holen + TreeNode *node = (TreeNode *)top(iteratorStack); + iteratorStack = pop(iteratorStack); + + // rechten Teilbaum + linke Kette pushen + TreeNode *right = node->right; + while (right != NULL) + { + iteratorStack = push(iteratorStack, right); + right = right->left; + } + + return node->data; } // Releases all memory resources (including data copies). void clearTree(TreeNode *root) { + if (root != NULL) + { + 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 == NULL) + return 0; + return 1 + treeSize(root->left) + treeSize(root->right); } \ No newline at end of file From adc3ebc8beb77d78f25d565008805257dace4dfd Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 00:33:30 +0100 Subject: [PATCH 07/14] makefile unitTest added --- I2_Dobble/makefile | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/I2_Dobble/makefile b/I2_Dobble/makefile index 328cc1a..24a5008 100644 --- a/I2_Dobble/makefile +++ b/I2_Dobble/makefile @@ -28,29 +28,38 @@ doble_initial: program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o doble : main.o $(program_obj_files) - $(CC) $(FLAGS) $(LDFLAGS) $^ -o doble + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o doble -$(program_obj_filesobj_files): %.o: %.c - $(CC) -c $(FLAGS) $^ -o $@ +$(program_obj_files): %.o: %.c + $(CC) -c $(CFLAGS) $^ -o $@ # -------------------------- # Unit Tests # -------------------------- -unitTests: numbersTest +unity_src = $(unityfolder)/unity.c + +unitTests: numbersTest stackTest bintreeTest ./runNumbersTest + ./runStackTest + ./runBintreeTest -numbersTest: numbers.o bintree.o numbersTest.o $($(unityfolder)/unity.c) - $(CC) $(FLAGS) $(LDFLAGS) $^ -o $@ +numbersTest: numbers.o bintree.o stack.o numbersTest.c $(unity_src) stack.o + $(CC) $(CFLAGS) $(LDFLAGS) -I$(unityfolder) $^ -o runNumbersTest +stackTest: stack.o stackTest.c $(unity_src) + $(CC) $(CFLAGS) $(LDFLAGS) -I$(unityfolder) $^ -o runStackTest + +bintreeTest: bintree.o bintreeTest.c $(unity_src) stack.o + $(CC) $(CFLAGS) $(LDFLAGS) -I$(unityfolder) $^ -o runBintreeTest %.o: %.c - $(CC) -c $(FLAGS) $< -o $@ + $(CC) -c $(CFLAGS) $< -o $@ # -------------------------- # Clean # -------------------------- clean: ifeq ($(OS),Windows_NT) - del /f *.o doble runNumbersTest doble_initial + del /f *.o doble doble_initial runNumbersTest runStackTest runBintreeTest else - rm -f *.o doble runNumbersTest doble_initial + rm -f *.o doble doble_initial runNumbersTest runStackTest runBintreeTest endif \ No newline at end of file From 2950b10931bcebbf622c096433df153c3315676d Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 10:17:58 +0100 Subject: [PATCH 08/14] binTreeTest added --- I2_Dobble/bintreeTest.c | 114 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 4 deletions(-) diff --git a/I2_Dobble/bintreeTest.c b/I2_Dobble/bintreeTest.c index 6642f9f..588060b 100644 --- a/I2_Dobble/bintreeTest.c +++ b/I2_Dobble/bintreeTest.c @@ -1,13 +1,119 @@ -#include "bintree.h" #include "unity.h" -#include "unity_internals.h" +#include "bintree.h" +#include + +static int compare(const void *a, const void *b) +{ + return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); +} void setUp(void) { } void tearDown(void) { } -int main() +void test_addToTree_single_element(void) +{ + TreeNode *root = NULL; + int value = 10; + int dup = -1; + + root = addToTree(root, &value, sizeof(int), compare, &dup); + + TEST_ASSERT_NOT_NULL(root); + TEST_ASSERT_EQUAL_INT(10, *(int*)root->data); + TEST_ASSERT_EQUAL_INT(0, dup); // neuer Eintrag + + clearTree(root); +} + +void test_addToTree_multiple_elements_and_size(void) +{ + TreeNode *root = NULL; + int values[] = {5, 3, 7, 1, 4}; + int dup = -1; + + for (int i = 0; i < 5; i++) + root = addToTree(root, &values[i], sizeof(int), compare, &dup); + + TEST_ASSERT_EQUAL_UINT(5, treeSize(root)); + + clearTree(root); +} + +void test_addToTree_duplicate_detection(void) +{ + TreeNode *root = NULL; + int val = 42; + int dup; + + root = addToTree(root, &val, sizeof(int), compare, &dup); + TEST_ASSERT_EQUAL(0, dup); + + addToTree(root, &val, sizeof(int), compare, &dup); + TEST_ASSERT_EQUAL(1, dup); + + clearTree(root); +} + +void test_treeSize_empty_tree_detection(void) +{ + TEST_ASSERT_EQUAL_UINT(0, treeSize(NULL)); +} + +void test_nextTreeData_returns_inorder(void) +{ + TreeNode *root = NULL; + int values[] = {5, 3, 7, 2, 4, 6, 8}; + + // Einfügen + for (int i = 0; i < 7; i++) + root = addToTree(root, &values[i], sizeof(int), compare, NULL); + + /* Erwartete Reihenfolge (inorder): 2,3,4,5,6,7,8 */ + int expected[] = {2,3,4,5,6,7,8}; + + int idx = 0; + void *p = nextTreeData(root); // Iterator starten + + while (p != NULL) + { + TEST_ASSERT_EQUAL_INT(expected[idx], *(int*)p); + idx++; + p = nextTreeData(NULL); // Fortsetzen mit NULL + } + + TEST_ASSERT_EQUAL(7, idx); //alle Einträge geprüft + + clearTree(root); +} + +void test_treeSize_returns_correct_size() +{ + TreeNode *root = NULL; + int values[] = {8, 3, 10, 1, 6, 14}; + + // ersten Baum aufbauen + for (int i = 0; i < 6; i++) + root = addToTree(root, &values[i], sizeof(int), compare, NULL); + + TEST_ASSERT_EQUAL_UINT(6, treeSize(root)); + + // Baum löschen + clearTree(root); + root = NULL; + + TEST_ASSERT_EQUAL_UINT(0, treeSize(root)); +} + +int main(void) { UNITY_BEGIN(); + RUN_TEST(test_addToTree_single_element); + RUN_TEST(test_addToTree_multiple_elements_and_size); + RUN_TEST(test_addToTree_duplicate_detection); + RUN_TEST(test_treeSize_empty_tree_detection); + RUN_TEST(test_nextTreeData_returns_inorder); + RUN_TEST(test_treeSize_returns_correct_size); + return UNITY_END(); -} \ No newline at end of file +} From 0d561c017505dbc1bce0c2f68ed82fca55633d57 Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 12:35:12 +0100 Subject: [PATCH 09/14] added stackTest --- I2_Dobble/stackTest.c | 93 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/I2_Dobble/stackTest.c b/I2_Dobble/stackTest.c index d58dc45..75ef216 100644 --- a/I2_Dobble/stackTest.c +++ b/I2_Dobble/stackTest.c @@ -5,9 +5,102 @@ void setUp(void) { } void tearDown(void) { } +void test_push_should_add_new_node_at_top(void) +{ + StackNode *stack = NULL; + + int value = 42; + stack = push(stack, &value); + + TEST_ASSERT_NOT_NULL(stack); + TEST_ASSERT_EQUAL_PTR(&value, stack->data); + TEST_ASSERT_NULL(stack->next); + + clearStack(stack); +} + +void test_push_multiple_should_chain_nodes_correctly(void) +{ + int a = 1, b = 2; + + StackNode *first = push(NULL, &a); + + StackNode *second = push(first, &b); + + TEST_ASSERT_EQUAL_PTR(&b, second->data); + TEST_ASSERT_EQUAL_PTR(first, second->next); + TEST_ASSERT_EQUAL_PTR(&a, first->data); + + clearStack(second); +} + +void test_top_should_return_null_on_empty_stack(void) +{ + StackNode *stack = NULL; + TEST_ASSERT_NULL(top(stack)); +} + +void test_top_should_return_data_of_existing_node(void) +{ + StackNode node; + int x = 99; + + node.data = &x; + node.next = NULL; + + TEST_ASSERT_EQUAL_PTR(&x, top(&node)); +} + +void test_pop_should_return_null_when_stack_empty(void) +{ + StackNode *stack = NULL; + TEST_ASSERT_NULL(pop(stack)); +} + +void test_pop_should_remove_single_element(void) +{ + StackNode *stack = malloc(sizeof(StackNode)); + int x = 7; + + stack->data = &x; + stack->next = NULL; + + StackNode *result = pop(stack); + + TEST_ASSERT_NULL(result); // Kein Element mehr übrig +} + +void test_pop_should_remove_top_node_only(void) +{ + // Manuell verkettete Liste aufbauen + StackNode *n1 = malloc(sizeof(StackNode)); + StackNode *n2 = malloc(sizeof(StackNode)); + int a = 1, b = 2; + + n1->data = &a; + n1->next = NULL; + + n2->data = &b; + n2->next = n1; + + StackNode *result = pop(n2); + + TEST_ASSERT_EQUAL_PTR(n1, result); + + clearStack(result); +} + int main() { UNITY_BEGIN(); + RUN_TEST(test_push_should_add_new_node_at_top); + RUN_TEST(test_push_multiple_should_chain_nodes_correctly); + RUN_TEST(test_top_should_return_null_on_empty_stack); + RUN_TEST(test_top_should_return_data_of_existing_node); + RUN_TEST(test_pop_should_return_null_when_stack_empty); + RUN_TEST(test_pop_should_remove_single_element); + RUN_TEST(test_pop_should_remove_top_node_only); + return UNITY_END(); } \ No newline at end of file From 7780bddc535de7930e4800e9a2b7e730303771ff Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 Nov 2025 12:37:24 +0100 Subject: [PATCH 10/14] small fixes --- .gitignore | 3 ++- I2_Dobble/makefile | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4eb9950..1cec025 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ !**/*.c !**/*.h !**/*Makefile -!**/*.md \ No newline at end of file +!**/*.md +I2_Dobble/highscores.txt diff --git a/I2_Dobble/makefile b/I2_Dobble/makefile index 24a5008..6fd6185 100644 --- a/I2_Dobble/makefile +++ b/I2_Dobble/makefile @@ -1,6 +1,5 @@ CC = gcc CFLAGS = -g -Wall -LDFLAGS = -lm ifeq ($(OS),Windows_NT) include makefile_windows.variables From 52e83f52a2dc03694754be84a8231ef16e6776aa Mon Sep 17 00:00:00 2001 From: Jonas Date: Sun, 23 Nov 2025 17:02:09 +0100 Subject: [PATCH 11/14] fix dublicate was at the end at all time --- I2_Dobble/numbers.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/I2_Dobble/numbers.c b/I2_Dobble/numbers.c index 5817686..fea8960 100644 --- a/I2_Dobble/numbers.c +++ b/I2_Dobble/numbers.c @@ -11,14 +11,22 @@ * Duplizieren eines zufälligen Eintrags im Array. * in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */ -// 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. +static void dublicateRandomEntry (unsigned int *numbers, unsigned int len) +{ + unsigned int dubIndx = rand() % len; + unsigned int copyIndx = rand() % len; + + numbers[copyIndx] = numbers[dubIndx]; +} + static int compare(const void *a, const void *b) { return (*(int *)a > *(int *)b) - (*(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) { if (len < 2) @@ -48,8 +56,7 @@ unsigned int *createNumbers(unsigned int len) } // Duplicate one random entry - unsigned int dupIndex = rand() % (len - 1); - numbers[len - 1] = numbers[dupIndex]; + dublicateRandomEntry(numbers, len); clearTree(root); //Notwendigkeit muss noch restlichem Code entnommen werden return numbers; From 40a6501fde4a4b76a3c1e73740a797ae705525ac Mon Sep 17 00:00:00 2001 From: Jonas Date: Sun, 23 Nov 2025 17:29:45 +0100 Subject: [PATCH 12/14] fixing error in dublicateRandomEntry --- I2_Dobble/numbers.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/I2_Dobble/numbers.c b/I2_Dobble/numbers.c index fea8960..f3f23d2 100644 --- a/I2_Dobble/numbers.c +++ b/I2_Dobble/numbers.c @@ -13,10 +13,23 @@ static void dublicateRandomEntry (unsigned int *numbers, unsigned int len) { - unsigned int dubIndx = rand() % len; - unsigned int copyIndx = rand() % len; + if (numbers && len > 2) + { + unsigned int dubIndx = rand() % len; + unsigned int copyIndx; + + do { + copyIndx = rand() % len; + } while (copyIndx == dubIndx); - numbers[copyIndx] = numbers[dubIndx]; + numbers[len - 1] = numbers[dubIndx]; + + //switching last entry with random other entry + unsigned int temp; + temp = numbers[copyIndx]; + numbers[copyIndx] = numbers[len - 1]; + numbers[len - 1] = temp; + } } static int compare(const void *a, const void *b) From 9a8a346a1ea957814f25e0e7a2ee821df80a67e1 Mon Sep 17 00:00:00 2001 From: Jonas Date: Tue, 25 Nov 2025 22:01:56 +0100 Subject: [PATCH 13/14] small fix --- I2_Dobble/number.md | 9 ++++++--- I2_Dobble/numbers.c | 6 ++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/I2_Dobble/number.md b/I2_Dobble/number.md index 4548262..305e726 100644 --- a/I2_Dobble/number.md +++ b/I2_Dobble/number.md @@ -1,4 +1,4 @@ -*createNumbers: +*createNumbers: -> numbers array gets filled with random entry with only one dublicate -> check if len is greater than 2 -> create new array numbers, use malloc and check if correct @@ -7,7 +7,10 @@ -> add new value to tree using addToTree and rand() -> addToTree sets isDup to 1, if value already exists -> if value does not already exist -> add to numbers[] --> +-> stops at numbers[len -2] +static dublicateRandomEntry: +-> numbers[len-1] is filled with random already existing number +-> numbers[len -1] gets switched with other random entry -> dublicate is placed randwom in entry; without the switch, dublicate would always be at the end getDublicate: @@ -15,7 +18,7 @@ getDublicate: -> numbers (Zeiger != NULL) und len (min. 2) check -> define new array numbersCopy -> copy numbers to numbersCopy - -> simple loop to copy each element number -> numbersCopy + -> simple loop to copy each element from numbers to numbersCopy -> sort numbersCopy with qsort -> compare each element of numbersCopy with next element (if numbersCopy[i] == numbersCopy[i+1] -> dublicate was found, because same values are right next to each other) -> return found dublicate diff --git a/I2_Dobble/numbers.c b/I2_Dobble/numbers.c index f3f23d2..8f6bda6 100644 --- a/I2_Dobble/numbers.c +++ b/I2_Dobble/numbers.c @@ -15,12 +15,10 @@ static void dublicateRandomEntry (unsigned int *numbers, unsigned int len) { if (numbers && len > 2) { - unsigned int dubIndx = rand() % len; + unsigned int dubIndx = rand() % (len - 1); unsigned int copyIndx; - do { - copyIndx = rand() % len; - } while (copyIndx == dubIndx); + copyIndx = rand() % len; numbers[len - 1] = numbers[dubIndx]; From ef8340ba6b9e7a4d6bac8d0eb9b4b987a9316088 Mon Sep 17 00:00:00 2001 From: Jonas Date: Mon, 1 Dec 2025 15:18:13 +0100 Subject: [PATCH 14/14] bintree.md added --- I2_Dobble/bintree.c | 3 +- I2_Dobble/bintree.md | 100 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 I2_Dobble/bintree.md diff --git a/I2_Dobble/bintree.c b/I2_Dobble/bintree.c index ace0cb4..6126d18 100644 --- a/I2_Dobble/bintree.c +++ b/I2_Dobble/bintree.c @@ -60,7 +60,6 @@ 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) { - // Neues Traversieren? if (root != NULL) { clearStack(iteratorStack); @@ -75,7 +74,7 @@ void *nextTreeData(TreeNode *root) } } - // Wenn Stack leer → fertig + // Wenn Stack leer -> fertig if (iteratorStack == NULL) return NULL; diff --git a/I2_Dobble/bintree.md b/I2_Dobble/bintree.md new file mode 100644 index 0000000..2669dec --- /dev/null +++ b/I2_Dobble/bintree.md @@ -0,0 +1,100 @@ +1) static StackNode *iteratorStack = NULL + -> Stack für nextTreeData + -> wird verwendet um nach und nach die Zahlen von klein nach groß auszugeben + -> muss da so stehen, weil ansonsten nextTreeData immer von vorne anfängt + +2) addToTree -> soll ein Element an die richtige Stelle im Baum hinzufügen + -> wenn keine root angegeben ist (wenn entweder kein Baum vorhanden ist, oder die richtige Stelle gefunden wurde) soll ein neue Node erstellt werden. + -> Speicher reservieren + -> data nach newNode.data kopieren (memcpy) kopiert einfach nur den Inhalt ohne ihn zu interpretieren + -> pointer links und rechts werden NULL gesetzt, da keine anderen Datan vorhanden sind + -> isDublicate = 0, da kein Dublikat vorhanden sein kann + + -> root.data wird mit data verglichen (größer, kleiner, gleich), um zu entscheiden, ob rechts oder links eingefügt werden soll + -> gleich -> Dublikat -> einfügen verhindern + -> größer -> rechts einfügen + -> kleiner -> links einfügen + + -> eingefügt wird, in dem addToTree erneut aufgerufen wird, aber jetzt als root root.left/root.right übergeben wird + -> es wird erneut verglichen und wieder in den rechten, bzw. linken Teilbaum eingefügt, solange bis richtige Stelle im Baum erreicht ist -> einfügen des Wertes + +3) nextTreeData + -> soll nacheinander die Werte des Binärbaums der größe nach ausgeben + -> Diese Funktion beruht auf einem richtigen Binär Baum (werte stehen an der richtigen Stelle) + -> dabei wird der iteratorStack verwendet, auf diesem sind immer Teilbereiche unseres Binärbaums vorhanden (in sortierter Reihenfolge), allerdings ist er nie vollständig, sondern wird im laufe des Programms immer durch fehlende Werte ergänzt + + -> wenn root != NULL -> neuer Beginn bei einem ggf. anderen Baum + -> iteratorStack wird gelöscht um eventuelle "Rückstände" zu beseitigen + -> danach werden erstmal immer die jeweils linken Nodes in den Stack gepusht + -> im Stack liegt nun die kleinste Node ganz oben, danach werden die Werte immer größer, allerdings fehlen noch Werte dazwischen + + -> anschließend wird sich die oberste Node aus dem Stack geholt und aus dem Stack entfernt -> Die ist der kleinste Wert im Baum und soll somit auch als erste zurückgegeben werden + -> jetzt wird auf dem Stack der rechte Teilbaum von unseren kleinsten Wert im Baum auf den Stack gepusht -> diese Werte sind alle größer als unsere Node, jedoch kleiner als die davor vorletzte Node im Stack -> DER STACK IST ALSO IMMER NOCH NACH DER GRÖßE SORTIERT + -> unser Stack hat jetzt den nächst größeren Wert im Baum als top Node -> ausgangssituation für nächsten Aufruf + -> gepeicherte node wird verwendet um node.data auszugeben + + + + Beispiel Baum: + + 12 + / \ + 8 15 + / \ \ + 5 9 17 + / \ + 16 20 + + 1) erst alle linken Nodes pushen -> 5 + 8 + 12 + + 2) top Node (5) speichern und aus Stack entfernen -> 8 + 12 + + 3) rechte Node und alle jeweils linken Nodes pushen -> 8 + 12 + 4) -> 5 wird ausgegeben (gepeicherte Node) + 5) neuer Aufruf + 6) top Node speichern (8) und aus Stack entfernen -> 12 + 7) rechte Node und alle jeweils linken Nodes pushen -> 9 + 12 + 8) -> 8 wird ausgegeben (gespeicherte Node) + 9) neuer Aufruf + 10) top Node speichern (9) und aus Stack entfernen -> 12 + 11) rechte Node und alle jeweils linken Nodes pushen -> 12 + 12) -> 9 wird ausgegeben (gespeicherte Node) + 13) neuer Aufruf + 14) top Node speichern (12) und aus Stack entfernen -> NULL + 15) rechte Node und alle jeweils linken Nodes pushen -> 15 + 16) -> 12 wird ausgegeben (gespeicherte Node) + 17) neuer Aufruf + 18) top Node speichern (15) und aus Stack entfernen -> NULL + 19) rechte Node und alle jeweils linken Nodes pushen -> 16 + 17 + 20) -> 15 wird ausgegeben (gespeicherte Node) + 21) neuer Aufruf + 22) top Node speichern (16) und aus Stack entfernen -> 17 + 23) rechte Node und alle jeweils linken Nodes pushen -> 17 + 24) -> 16 wird ausgegeben (gespeicherte Node) + 25) neuer Aufruf + 26) top Node speichern (17) und aus Stack entfernen -> NULL + 27) rechte Node und alle jeweils linken Nodes pushen -> 20 + 28) -> 17 wird ausgegeben (gespeicherte Node) + 29) neuer Aufruf + 30) top Node speichern (20) und aus Stack entfernen -> NULL + 31) rechte Node und alle jeweils linken Nodes pushen -> NULL + 32) -> 20 wird ausgegeben (gespeicherte Node) + 33) neuer Aufruf -> Stack = NULL -> fertig + + +4) treeSize + -> rekursiver Aufruf der Funktion + + -> es wird jeweils die jeweils linke und rechte Node als neue root genommen + -> aufruf mit treeSize(root->left / root -> right) + -> es wird pro aufruf +1 gerechnet + -> am Ende wird die Node Anzahl zurückgegeben + + +