Compare commits

...
27 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
Thilo 6dc857cc63 added stack and test file 2025-12-09 17:37:26 +01:00
Thilo 9363ed22aa Added stack function 2025-12-07 15:16:00 +01:00
11 changed files with 670 additions and 20 deletions

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc.exe build active file",
"command": "C:\\ProgramData\\mingw64\\mingw64\\bin\\gcc.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
+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);
} }
BIN
View File
Binary file not shown.
+9
View File
@@ -1 +1,10 @@
thilo;19753
thilo;14880
max;14849
thilo;14733
player1;9956
player2;4988
player1;4980
player_name;4980
player2;4885
player1;3999 player1;3999
+31 -4
View File
@@ -35,15 +35,42 @@ $(program_obj_filesobj_files): %.o: %.c
# -------------------------- # --------------------------
# Unit Tests # Unit Tests
# -------------------------- # --------------------------
unitTests: stack_test_sources = test_stack.c stack.c
echo "needs to be implemented" stack_test_objects = $(stack_test_sources:.c=.o)
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 $@
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 "Running Unit Tests..."
@echo "============================="
./stack_test_runner
./numbers_test_runner
./bintree_test_runner
@echo "============================="
@echo "Unit Tests Finished."
@echo "============================="
# -------------------------- # --------------------------
# Clean # Clean
# -------------------------- # --------------------------
clean: clean:
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
del /f *.o doble del /f *.o doble test_runner
else else
rm -f *.o doble rm -f *.o doble test_runner
endif endif
+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;
} }
+49
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:
@@ -10,24 +11,72 @@
// Pushes data as pointer onto the stack. // Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data) StackNode *push(StackNode *stack, void *data)
{ {
StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));
if(newNode == NULL)
{
fprintf(stderr,"Fehler! Der Speicher für den neuen StackNode konnte nicht allokiert werden!\n");
return stack;
}
newNode->data = data; //saves data in newNode
newNode->next = stack; //pushes the newNode on top of stack (newNode->next points to previous Top-Node)
return newNode;
} }
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be // Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
// freed by caller.) // freed by caller.)
StackNode *pop(StackNode *stack) StackNode *pop(StackNode *stack)
{ {
if (stack == NULL)
{
fprintf(stderr,"Fehler! Stack darf zum poppen nicht leer sein!\n");
return stack;
}
StackNode *old = stack; //temporary pointer to old top of stack
stack= stack->next; //update stack pointer to point to next element
free(old); //free the memory of the old StackNode (old->data is not beeing freed)
return stack;
} }
// Returns the data of the top element. // Returns the data of the top element.
void *top(StackNode *stack) void *top(StackNode *stack)
{ {
if (stack == NULL)
{
fprintf(stderr,"Fehler! Kann von einem leeren Stack nicht das oberste Element lesen!\n");
return NULL;
}
void *data = stack->data;
return data;
} }
// Clears stack and releases all memory. // Clears stack and releases all memory.
void clearStack(StackNode *stack) void clearStack(StackNode *stack)
{ {
StackNode *current = stack;
StackNode *next;
while (current != NULL)
{
next = current->next;
if (current->data != NULL)
{
free(current->data);
current->data = NULL;
} }
free(current);
current = NULL;
current = next;
}
}
+6
View File
@@ -8,6 +8,12 @@ The latest element is taken from the stack. */
#include <stdlib.h> #include <stdlib.h>
//TODO: passenden Datentyp als struct anlegen //TODO: passenden Datentyp als struct anlegen
typedef struct StackNode
{
void *data;
struct StackNode *next;
} StackNode;
// Pushes data as pointer onto the stack. // Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data); StackNode *push(StackNode *stack, void *data);
+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;
}
+142
View File
@@ -0,0 +1,142 @@
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
void test_on_empty_stack(void)
{
char *status_a = "leer";
char *status_b = "leer";
StackNode *stack = NULL;
StackNode *a = pop(stack);
void* b = top(stack);
if (a == NULL)
{
status_a = "PASSED";
}
else status_a = "FAILED";
if (b == NULL)
{
status_b = "PASSED";
}
else status_b = "FAILED";
printf("Test on empty stack in pop: %s - Expected: NULL, Was: %p\n",status_a, (void*)a);
printf("Test on empty stack in top: %s - Expected: NULL, Was: %p\n",status_b, b);
}
void test_push(void)
{
int a[3] = {0};
StackNode *stack = NULL;
for (int i = 1; i < 4; i++)
{
int *var_push = malloc(sizeof(int));
if (var_push == NULL)
{
printf("Error in allocating memory in test_push!\n");
exit(EXIT_FAILURE);
}
*var_push = i;
stack = push(stack, var_push);
void *top_data = top(stack);
if (top_data != NULL && *(int*)top_data == i) {
a[i-1] = 1;
} else {
a[i-1] = 0;
}
}
if (a[0] == 1 && a[1] == 1 && a[2] == 1)
{
printf("Test push: SUCCEESS!\n");
}
else printf("Test pus: FAILED - Expected: all 1, Was: %d, %d, %d\n", a[0], a[1], a[2]);
clearStack(stack);
}
void test_pop(void)
{
StackNode *stack = NULL;
int *var_push = malloc(sizeof(int));
if (var_push == NULL)
{
fprintf(stderr, "Error in allocating memory in test_pop! Exiting.\n");
exit(EXIT_FAILURE);
}
*var_push = 1;
stack = push(stack, var_push);
stack = pop(stack);
if (stack == NULL) printf("Test pop: SUCCESS!\n");
else printf("Test pop: FAIL! - Stack is not empty! Head: %p\n", (void*)stack);
clearStack(stack);
}
void test_top(void)
{
StackNode *stack = NULL;
int *var_push = malloc(sizeof(int));
*var_push = 1;
stack = push(stack, var_push);
void *b = top(stack);
if (b != 0 && *(int*)b == 1) printf("Test top: SUCCESS!\n");
else printf("Test top: FAIL! - Expected 1, was %p\n", b);
clearStack(stack);
}
void test_clearStack(void)
{
StackNode *stack = NULL;
for (int i = 1; i < 4; i++)
{
int *var_push = malloc(sizeof(int));
if (var_push == NULL)
{
fprintf(stderr, "Error in allocating memory in test_clearStack! Exiting.\n");
exit(EXIT_FAILURE);
}
*var_push = i;
stack = push(stack, var_push);
}
clearStack(stack);
void *a = top(stack);
if (a == NULL) printf("Test clear: SUCESS!\n");
else printf("Test clear: FAILED! - Expected: NULL, Was: %p\n", a);
}
int main()
{
printf("============================\nStack Tests\n============================\n");
test_on_empty_stack();
test_push();
test_pop();
test_top();
test_clearStack();
return EXIT_SUCCESS;
}