Compare commits

...
25 Commits
Author SHA1 Message Date
ottma99059 b43402cc86 final changes completed 2025-12-16 12:26:33 +01:00
Thilo bbf0460d1a Final fix of doble numbers 2025-12-16 12:01:53 +01:00
Thilo 4b81d627f5 all bugs fixed 2025-12-16 11:52:11 +01:00
Thilo 326ad66959 Merge branch 'main' of https://git.efi.th-nuernberg.de/gitea/hoockth99140/Doble-Spiel 2025-12-16 11:51:45 +01:00
ottma99059 a118f4e920 binetree completely finisehd 2025-12-16 11:50:59 +01:00
Thilo 5941913b6c Merge branch 'main' of https://git.efi.th-nuernberg.de/gitea/hoockth99140/Doble-Spiel 2025-12-16 11:47:40 +01:00
Thilo b8f80512ba all bugs fixed 2025-12-16 11:46:55 +01:00
Thilo e9fa5b72a5 all bugs fixed 2025-12-16 11:46:12 +01:00
ottma99059 0a75187497 binetree changes 2025-12-16 11:42:05 +01:00
Thilo ce3de3b8f8 bug fixes! 2025-12-16 09:16:32 +01:00
ottma99059 353c4cfe6f changes bintree.c finished 2025-12-16 09:15:17 +01:00
ottma99059 da4ea358a3 changes bintree.c 2025-12-16 09:05:54 +01:00
ottma99059 0dd1564ba5 code finished 2025-12-15 23:11:46 +01:00
ottma99059 7d5caa5ce7 changes bintree finished 2025-12-15 23:11:46 +01:00
Thilo 0ebd521d61 numbers and tests finished 2025-12-15 20:13:58 +01:00
Thilo cb6a9feab8 numbers and tests finished 2025-12-15 20:09:10 +01:00
ottma99059 5532cec3ad added compareFct and fillArray 2025-12-13 12:14:33 +01:00
ottma99059 c47a735954 test_bintree komplett 2025-12-13 11:03:58 +01:00
ottma99059 58abc8a774 code_komplett 2025-12-11 16:32:25 +01:00
Thilo 5efe99e6d6 Merge branch 'main' of https://git.efi.th-nuernberg.de/gitea/hoockth99140/Doble-Spiel 2025-12-10 18:09:08 +01:00
Thilo d698dc8a4b stack.c updated 2025-12-10 18:08:18 +01:00
Thilo a74f52368c numbers.c finished 2025-12-10 18:07:21 +01:00
ottma99059 39e0758dbd code_2 2025-12-10 17:53:26 +01:00
ottma99059 7135abe9a6 code_1 2025-12-10 17:37:42 +01:00
Thilo b75411fd99 added first function in numbers.c 2025-12-10 17:10:34 +01:00
8 changed files with 445 additions and 31 deletions

No files matched your search

+103 -14
View File
@@ -1,36 +1,125 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include "stack.h" #include "stack.h"
#include "bintree.h" #include "bintree.h"
//TODO: binären Suchbaum implementieren static StackNode *push_left(TreeNode *node, StackNode *stack);
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv),
* `clearTree`: gibt den gesamten Baum frei (rekursiv),
* `treeSize`: zählt die Knoten im Baum (rekursiv),
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates // Vergleichsfunktion
// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). int compareFct(const void *argument1, const void *argument2)
{
int x = *((int *)argument1);
int y = *((int *)argument2);
if (x < y) return -1;
if (x > y) return 1;
return 0;
}
// Erzeugt einen neuen Baumknoten mit Datenkopie
static TreeNode *create_node(const void *data, size_t data_size)
{
TreeNode *node = malloc(sizeof(TreeNode)); // Speicher für neuen Knoten reservieren
if (!node)
{
perror("Speicher wurde NICHT reserviert!");
return NULL;
}
node->data = malloc(data_size); // Speicher für Knotendaten reservieren
if (!node->data)
{
perror("Speicher wurde NICHT reserviert!");
free(node);
return NULL;
}
memcpy(node->data, data, data_size); // Daten in neuen Speicher kopieren
node->left = NULL; // Linken Kindzeiger initialisieren
node->right = NULL; // Rechten Kindzeiger initialisieren
return node; // Zeiger auf neuen Knoten zurückgeben
}
//Fügt Daten in den Binärbaum ein
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 == NULL) // Wenn Baum leer ist (Ende erreicht)
{
if (isDuplicate)
*isDuplicate = 0; // Kein Duplikat, da neu eingefügt
return create_node(data, dataSize);
} }
// 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. int cmp = compareFct(data, root->data); // Daten mit aktuellem Knoten vergleichen
// 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. if (cmp < 0)
{
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
}
else if (cmp > 0)
{
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
}
else
{
if (isDuplicate)
*isDuplicate = 1;
}
return root; // Wurzel unverändert zurückgeben
}
// Inorder-Iterator über den Baum
void *nextTreeData(TreeNode *root) void *nextTreeData(TreeNode *root)
{ {
static StackNode *stack = NULL;
/* Linken Pfad auf Stack legen */
if (root != NULL)
stack = push_left(root, stack); // Linken Pfad ab root auf Stack legen
if (stack == NULL)
return NULL;
TreeNode *node = (TreeNode *)top(stack); // Oberstes Element vom Stack holen
stack = pop(stack);
if (node->right != NULL) // Wenn rechter Teilbaum existiert
stack = push_left(node->right, stack); // Linken Pfad vom rechten Kind auf Stack legen
return node->data; // Daten des Knotens zurückgeben
} }
// Releases all memory resources (including data copies). // Hilfsfunktion: linken Pfad auf Stack legen
static StackNode *push_left(TreeNode *node, StackNode *stack)
{
while (node != NULL) // Solange linkes Kind existiert
{
stack = push(stack, node); // Knoten auf Stack legen
node = node->left;
}
return stack;
}
// Gibt gesamten Baum frei
void clearTree(TreeNode *root) void clearTree(TreeNode *root)
{ {
if (root == NULL)
return;
clearTree(root->left);
clearTree(root->right);
free(root->data);
free(root);
} }
// Liefert Anzahl der Knoten
// Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root) unsigned int treeSize(const TreeNode *root)
{ {
if (root == NULL)
return 0;
return 1 + treeSize(root->left) + treeSize(root->right);
} }
+8
View File
@@ -1,2 +1,10 @@
thilo;19753
thilo;14880
max;14849
thilo;14733
player1;9956
player2;4988
player1;4980
player_name;4980 player_name;4980
player2;4885
player1;3999 player1;3999
+21 -7
View File
@@ -35,19 +35,33 @@ $(program_obj_filesobj_files): %.o: %.c
# -------------------------- # --------------------------
# Unit Tests # Unit Tests
# -------------------------- # --------------------------
tets_sources = test_stack.c stack.c stack_test_sources = test_stack.c stack.c
test_objects = $(test_sources:.c=.o) stack_test_objects = $(stack_test_sources:.c=.o)
test_runner: $(test_objects) numbers_test_sources = test_numbers.c numbers.c
numbers_test_objects = $(numbers_test_sources:.c=.o)
bintree_test_sources = test_bintree.c bintree.c
bintree_test_objects = $(bintree_test_sources:.c=.o)
stack_test_runner: $(stack_test_objects)
$(CC) $(FLAGS) $^ -o $@ $(CC) $(FLAGS) $^ -o $@
unitTests: test_runner numbers_test_runner: $(numbers_test_objects)
$(CC) $(FLAGS) $^ -o $@
bintree_test_runner: $(bintree_test_objects)
$(CC) $(FLAGS) $^ -o $@
unitTests: stack_test_runner numbers_test_runner bintree_test_runner
@echo "=============================" @echo "============================="
@echo "Running Stack Unit Tests..." @echo "Running Unit Tests..."
@echo "=============================" @echo "============================="
./test_runner ./stack_test_runner
./numbers_test_runner
./bintree_test_runner
@echo "=============================" @echo "============================="
@echo "Stack Unit Tests Finished." @echo "Unit Tests Finished."
@echo "=============================" @echo "============================="
+127 -2
View File
@@ -6,21 +6,146 @@
#include "bintree.h" #include "bintree.h"
//TODO: getDuplicate und createNumbers implementieren //TODO: getDuplicate und createNumbers implementieren
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen. /* * * * Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
* Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
* Duplizieren eines zufälligen Eintrags im Array. * Duplizieren eines zufälligen Eintrags im Array.
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */ * 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 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 // Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
// creating random numbers. // creating random numbers.
static int compareFct(const void *argument1, const void *argument2)
{
unsigned int x = *(const unsigned int *)argument1;
unsigned int y = *(const unsigned int *)argument2;
if (x < y) return -1;
if (x > y) return 1;
return 0;
}
static void fillArray(unsigned int *array, unsigned int len)
{
TreeNode *root = NULL;
int isDuplicate;
unsigned int value;
unsigned int i = 0;
srand(time(NULL));
while (i < len)
{
value = rand() % (2 * len) + 1;
root = addToTree(root, &value, sizeof(unsigned int), compareFct, &isDuplicate);
if (isDuplicate == 0)
{
array[i] = value;
i++;
}
// Bei Duplikat: nochmal versuchen, kein Inkrement
}
clearTree(root);
}
unsigned int *createNumbers(unsigned int len) unsigned int *createNumbers(unsigned int len)
{ {
if (len < 2)
{
fprintf(stderr,"Fehler! Die Anzahl an Zahlen muss mindestens 2 sein!\n");
return NULL;
}
unsigned int *array = malloc(sizeof(unsigned int) * len);
if (array == NULL)
{
fprintf(stderr,"Fehler! Der Speicher für das Array konnte nicht reserviert werden!\n");
return NULL;
}
unsigned int position;
unsigned int duplicate_value;
unsigned int pos_dup;
srand(time(NULL));
/*for (unsigned int i = 0; i < len; i++)
{
array[i] = rand() % (2*len) + 1;
}
*/
TreeNode *root = NULL;
int isDuplicate;
unsigned int value;
unsigned int i = 0;
srand(time(NULL));
while (i < len)
{
value = rand() % (2 * len) + 1;
root = addToTree(root, &value, sizeof(unsigned int), compareFct, &isDuplicate);
if (isDuplicate == 0)
{
array[i] = value;
i++;
}
// Bei Duplikat: nochmal versuchen, kein Inkrement
}
clearTree(root);
position = rand() % len;
duplicate_value = array[position];
do
{
pos_dup = rand() % len;
} while (pos_dup == position);
array[pos_dup] = array[position];
return array;
} }
// Returns only the only number in numbers which is present twice. Returns zero on errors. // 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) unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{ {
unsigned int duplicate = 0;
if (numbers == NULL)
{
fprintf(stderr, "Fehler! Das übergebene Array ist leer!\n");
return duplicate;
}
if (len < 2)
{
fprintf(stderr,"Fehler! Die Anzahl an Zahlen muss mindestens 2 sein!\n");
return duplicate;
}
for (unsigned int i = 0; i < len - 1; i++)
{
for (unsigned int k = i + 1; k < len; k++)
{
if (numbers[i] == numbers[k])
{
duplicate = numbers[k];
return duplicate;
}
}
}
return duplicate;
} }
+5 -3
View File
@@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include "stack.h" #include "stack.h"
//TODO: grundlegende Stackfunktionen implementieren: //TODO: grundlegende Stackfunktionen implementieren:
@@ -14,7 +15,7 @@ StackNode *push(StackNode *stack, void *data)
if(newNode == NULL) if(newNode == NULL)
{ {
perror("Fehler! Der Speicher für den neuen StackNode konnte nicht allokiert werden!\n"); fprintf(stderr,"Fehler! Der Speicher für den neuen StackNode konnte nicht allokiert werden!\n");
return stack; return stack;
} }
@@ -30,7 +31,7 @@ StackNode *pop(StackNode *stack)
{ {
if (stack == NULL) if (stack == NULL)
{ {
perror("Fehler! Stack darf zum poppen nicht leer sein!\n"); fprintf(stderr,"Fehler! Stack darf zum poppen nicht leer sein!\n");
return stack; return stack;
} }
@@ -48,7 +49,7 @@ void *top(StackNode *stack)
{ {
if (stack == NULL) if (stack == NULL)
{ {
perror("Fehler! Kann von einem leeren Stack nicht das oberste Element lesen!\n"); fprintf(stderr,"Fehler! Kann von einem leeren Stack nicht das oberste Element lesen!\n");
return NULL; return NULL;
} }
void *data = stack->data; void *data = stack->data;
@@ -78,3 +79,4 @@ void clearStack(StackNode *stack)
current = next; current = next;
} }
} }
+103
View File
@@ -0,0 +1,103 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "bintree.h"
// Vergleichsfunktion für den Binärbaum (nur für Tests)
static int testCompareFct(const void *argument1, const void *argument2)
{
unsigned int x = *(const unsigned int *)argument1;
unsigned int y = *(const unsigned int *)argument2;
if (x > y) return 1;
if (x < y) return -1;
return 0;
}
// Unit-Test für die Vergleichsfunktion
void test_compareFct(void)
{
unsigned int a = 3, b = 5, c = 3;
assert(testCompareFct(&a, &b) < 0);
assert(testCompareFct(&b, &a) > 0);
assert(testCompareFct(&a, &c) == 0);
}
// Test für Einfügen und Baumgröße
void test_addToTree_and_treeSize(void)
{
TreeNode *root = NULL;
int isDuplicate;
int values[] = {5, 3, 7, 2, 4, 6, 8};
int n = sizeof(values) / sizeof(values[0]);
for (int i = 0; i < n; i++)
{
root = addToTree(root, &values[i], sizeof(int),
testCompareFct, &isDuplicate);
assert(isDuplicate == 0);
}
assert(treeSize(root) == 7);
clearTree(root);
}
// Test für Duplikaterkennung
void test_duplicates(void)
{
TreeNode *root = NULL;
int isDuplicate;
int value = 5;
root = addToTree(root, &value, sizeof(int),
testCompareFct, &isDuplicate);
assert(isDuplicate == 0);
root = addToTree(root, &value, sizeof(int),
testCompareFct, &isDuplicate);
assert(isDuplicate == 1);
clearTree(root);
}
// Test für Inorder-Traversierung
void test_nextTreeData(void)
{
TreeNode *root = NULL;
int isDuplicate;
int values[] = {5, 3, 7, 2, 4, 6, 8};
int expected[] = {2, 3, 4, 5, 6, 7, 8};
for (int i = 0; i < 7; i++)
{
root = addToTree(root, &values[i], sizeof(int),
testCompareFct, &isDuplicate);
}
for (int i = 0; i < 7; i++)
{
int *data = (int *)nextTreeData(root);
assert(data != NULL);
assert(*data == expected[i]);
}
assert(nextTreeData(NULL) == NULL);
clearTree(root);
}
int main(void)
{
test_compareFct();
test_addToTree_and_treeSize();
test_duplicates();
test_nextTreeData();
printf("Alle Unit-Tests erfolgreich bestanden.\n");
return 0;
}
+72
View File
@@ -0,0 +1,72 @@
#include <stdio.h>
#include <stdlib.h>
#include "numbers.h"
void test_empty_function(void)
{
unsigned int len1 = 1;
unsigned int len2 = 5;
unsigned int *null_array = NULL;
unsigned int array[] = {1, 2, 3, 4, 5};
unsigned int *array_ptr = array;
unsigned int *create_num = createNumbers(len1);
if (create_num == NULL)
printf("Test on invalid lenght of array: SUCCESS!\n");
else
{
printf("Test on invalid lenght of array: FAILED! Expected: NULL, Was: %p\n", create_num);
free(create_num);
}
unsigned int duplicate = getDuplicate(null_array, len2);
if (duplicate == 0)
printf("Test on invalid array: SUCESS!\n");
else
printf("Test on invalid array: FAILED! Expected: 0, WAS: %u\n", duplicate);
unsigned int duplicate2 = getDuplicate(array_ptr, len1);
if (duplicate2 == 0)
printf("Test on invalid lenght of array: SUCESS!\n");
else
printf("Test on invalid lenght of array: FAILED, Expected: 0, WAS: %u\n", duplicate2);
}
void test_array(void)
{
unsigned int len = 10;
unsigned int *array = NULL;
array = createNumbers(len);
if (array == NULL)
printf("Test on valid lenght of array: FAILED! Expected array greater than 0, Was: NULL\n");
else printf("Test on valid lenght of array: SUCESS!\n");
unsigned int test_array_dup[] = {1, 2, 3, 4, 5, 2, 6, 7, 8, 9};
unsigned int test_len = 10;
unsigned int duplicate = 2;
unsigned int duplicate_found = getDuplicate(test_array_dup, test_len);
if (duplicate_found != duplicate)
printf("Test on valid lenght of array: FAILED! Expected %u, Was: %u\n", duplicate, duplicate_found);
else printf("Test on valid lenght of array: SUCESS!, Duplicate value: %d\n", duplicate);
free(array);
}
int main(void)
{
test_empty_function();
printf("\n");
test_array();
return EXIT_SUCCESS;
}
+6 -5
View File
@@ -31,7 +31,7 @@ void test_on_empty_stack(void)
void test_push(void) void test_push(void)
{ {
int a[3] = 0; int a[3] = {0};
StackNode *stack = NULL; StackNode *stack = NULL;
for (int i = 1; i < 4; i++) for (int i = 1; i < 4; i++)
@@ -62,7 +62,7 @@ void test_push(void)
else printf("Test pus: FAILED - Expected: all 1, Was: %d, %d, %d\n", a[0], a[1], a[2]); else printf("Test pus: FAILED - Expected: all 1, Was: %d, %d, %d\n", a[0], a[1], a[2]);
stack = clearStack(stack); clearStack(stack);
} }
void test_pop(void) void test_pop(void)
@@ -84,7 +84,7 @@ void test_pop(void)
else printf("Test pop: FAIL! - Stack is not empty! Head: %p\n", (void*)stack); else printf("Test pop: FAIL! - Stack is not empty! Head: %p\n", (void*)stack);
stack = clearStack(stack); clearStack(stack);
} }
void test_top(void) void test_top(void)
@@ -99,7 +99,7 @@ void test_top(void)
else printf("Test top: FAIL! - Expected 1, was %p\n", b); else printf("Test top: FAIL! - Expected 1, was %p\n", b);
stack = clearStack(stack); clearStack(stack);
} }
void test_clearStack(void) void test_clearStack(void)
@@ -120,7 +120,8 @@ void test_clearStack(void)
stack = push(stack, var_push); stack = push(stack, var_push);
} }
stack = clearStack(stack); clearStack(stack);
void *a = top(stack); void *a = top(stack);
if (a == NULL) printf("Test clear: SUCESS!\n"); if (a == NULL) printf("Test clear: SUCESS!\n");