Compare commits

...

38 Commits
main ... RMax

Author SHA1 Message Date
Max-R
c3b1cdd3a3 numbers 2025-12-09 10:37:20 +01:00
Max-R
9d32e06f3a highscores kristin geknackt 2025-12-09 10:27:42 +01:00
Max-R
9268113f38 mein clean 2025-12-09 10:21:16 +01:00
Max-R
8f2dfb507c Merge remote-tracking branch 'origin/Krisp' into RMax 2025-12-09 10:19:21 +01:00
Kristin
9bf5e6a541 stacktest clearstack pointer null setzen 2025-12-09 10:10:13 +01:00
Kristin
57f9914e2b stacktest überarbeitet 2025-12-09 09:57:41 +01:00
Kristin
09d7f457dd stacktest überarbeitet 2025-12-09 09:49:46 +01:00
Kristin
13cb5d8c86 push test im teststack verbessert 2025-12-09 09:13:18 +01:00
Kristin
6528686fb0 Fehler bei nichtreservierung von Speicher, stack.c kommentiert 2025-12-07 20:11:40 +01:00
Kristin
a3d0585ac1 stack.c eingebunden 2025-12-07 19:05:11 +01:00
Kristin
68563ec297 erste version 2025-12-07 18:35:22 +01:00
Max-R
8cccbcf441 makefile änderung 2025-12-05 12:08:25 +01:00
Max-R
96a97c07c9 Merge remote-tracking branch 'origin/tobi_experimental' into RMax 2025-12-05 12:05:01 +01:00
74fdcf500f stack.c test laufen alle 2025-12-05 11:54:23 +01:00
Kristin
55532cbb42 makefile mit rm 2025-12-05 11:52:08 +01:00
Kristin
d3904ac6e4 alle tests 2025-12-05 11:50:51 +01:00
Max-R
0575eac07e immer noch ohne clearstak 2025-12-05 11:47:36 +01:00
Kristin
5e96ec050c test_stack mit & 2025-12-05 11:24:35 +01:00
382c36b1b4 Merge remote-tracking branch 'origin/RMax' into tobi_experimental 2025-12-05 11:16:21 +01:00
81de4b3d36 arbeiten an stack.c 2025-12-05 11:13:27 +01:00
Kristin
f42a997683 clearstack mit ** 2025-12-05 11:12:30 +01:00
Max-R
09426ae40a tests bis auf clearstack laufen 2025-12-05 11:10:20 +01:00
Max-R
9443171664 create node 2025-12-05 11:04:09 +01:00
Max-R
b28deeaafb mhm 2025-12-05 10:53:03 +01:00
Max-R
4bb0d7516e stak.c 2025-12-05 10:48:10 +01:00
Max-R
ddd4132e1f erste tests stack.c 2025-12-05 10:41:30 +01:00
624a7d8b41 slight changes to stackNode struct, void func, etc 2025-12-05 10:41:08 +01:00
73ebc36c05 Merge branch 'KrispTobi' into tobi_experimental 2025-12-05 10:31:47 +01:00
Max-R
e7423f0a20 stack.c 2025-12-05 10:26:10 +01:00
Kristin
8b44089f23 Remove object files 2025-12-05 10:25:10 +01:00
Kristin
654fb615a2 Remove object files 2025-12-05 10:24:32 +01:00
Kristin
422ac38d54 gitignore 2025-12-05 10:21:33 +01:00
Max-R
7051134256 stack.h 2025-12-05 10:21:00 +01:00
Kristin
90612e4d04 stack.c 2025-12-05 10:20:17 +01:00
Kristin
17f4155891 stack.c 2025-12-05 10:08:55 +01:00
Max-R
735195460c mein Branch 2025-12-02 10:44:15 +01:00
Kristin
a002901e2f highscore.txt zu gitignore 2025-12-02 10:40:28 +01:00
Kristin
55b25a227b makefile 2025-12-02 10:32:52 +01:00
17 changed files with 762 additions and 80 deletions

4
.gitignore vendored
View File

@ -1 +1,3 @@
highscores.txt
doble_initial.exe
*.o
*.exe

18
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "windows-gcc-x64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "C:/ProgramData/mingw64/mingw64/bin/gcc.exe",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "windows-gcc-x64",
"compilerArgs": [
""
]
}
],
"version": 4
}

24
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,24 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"externalConsole": true,
"cwd": "c:/Users/Max-R/I2Pr/info2Praktikum-DobleSpiel",
"program": "c:/Users/Max-R/I2Pr/info2Praktikum-DobleSpiel/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

59
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,59 @@
{
"C_Cpp_Runner.cCompilerPath": "gcc",
"C_Cpp_Runner.cppCompilerPath": "g++",
"C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wcast-align",
"-Wconversion",
"-Wsign-conversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.msvcWarnings": [
"/W4",
"/permissive-",
"/w14242",
"/w14287",
"/w14296",
"/w14311",
"/w14826",
"/w44062",
"/w44242",
"/w14905",
"/w14906",
"/w14263",
"/w44265",
"/w14928"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false,
"C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false
}

121
bintree.c
View File

@ -1,36 +1,119 @@
#include <string.h>
#include "stack.h"
#include "bintree.h"
#include "stack.h"
#include <string.h>
//TODO: binären Suchbaum implementieren
// TODO: binären Suchbaum implementieren
/* * `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. */
* `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
// 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)
{
// typedef int (*CompareFctType)(const void *arg1, const void *arg2);
// 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).
void copyData(void *dest, const void *src, size_t size) {
unsigned char *d = dest;
const unsigned char *s = src;
for (size_t i = 0; i < size; i++) {
d[i] = s[i];
}
}
// 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.
// 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.
void *nextTreeData(TreeNode *root)
{
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize,
CompareFctType compareFct, int *isDuplicate) {
// isDuplicate initialisieren (auf 0 setzen)
if (isDuplicate) {
*isDuplicate = 0;
}
// leerer Baum
if (root == NULL) {
TreeNode *node = malloc(sizeof(TreeNode));
node->data = malloc(dataSize);
copyData(node->data, data, dataSize);
node->left = NULL;
node->right = NULL;
return node;
}
// mit compareFct <0 links >0 rechts =0 Duplikat
int cmp = compareFct(data, root->data);
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 {
// isDuplicate auf 1 setzen
if (isDuplicate) {
*isDuplicate = 1;
}
}
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. 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.
void *nextTreeData(TreeNode *root) {
static StackNode *stack = NULL;
// Neue Iteration starten
if (root != NULL) {
clearStack(&stack);
TreeNode *curr = root;
while (curr != NULL) {
StackNode *oldStack = stack;
StackNode *newStack = push(stack, curr);
if (newStack == oldStack)
return NULL; // push fehlgeschlagen
stack = newStack;
curr = curr->left;
}
}
if (stack == NULL)
return NULL; // alles durchlaufen
// Oberstes Element abrufen
TreeNode *node = (TreeNode *)top(stack);
stack = pop(stack);
// Rechten Teilbaum pushen
TreeNode *curr = node->right;
while (curr != NULL) {
StackNode *oldStack = stack;
StackNode *newStack = push(stack, curr);
if (newStack == oldStack)
return NULL; // push fehlgeschlagen
stack = newStack;
curr = curr->left;
}
return node->data;
}
// Releases all memory resources (including data copies).
void clearTree(TreeNode *root)
{
void clearTree(TreeNode *root) {
if (root == NULL)
return;
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)
{
unsigned int treeSize(const TreeNode *root) {
if (root == NULL)
return 0;
return 1 + treeSize(root->left) + treeSize(root->right);
}

View File

@ -5,19 +5,24 @@
typedef int (*CompareFctType)(const void *arg1, const void *arg2);
typedef struct node
{
void *data;
struct node *left;
struct node *right;
typedef struct node {
void *data;
struct node *left;
struct node *right;
} TreeNode;
// 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);
// 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.
// 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.
void copyData(void *dest, const void *src, size_t size);
// 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);
// 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. 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.
void *nextTreeData(TreeNode *root);
// Releases all memory resources (including data copies).
void clearTree(TreeNode *root);

BIN
doble_initial.exe Normal file

Binary file not shown.

View File

@ -1 +1,10 @@
player1;3999
max10;9970
max;9965
Kristin;9944
Kristin;7947
Kristin;6962
Kristin;5987
Kristin;5975
krisp;4986
krisp;4985
Kristin;4972

View File

@ -1,5 +1,6 @@
CC = gcc
FLAGS = -g -Wall -lm
ASAN_FLAGS = -fsanitize=address
ifeq ($(OS),Windows_NT)
include makefile_windows.variables
@ -24,19 +25,46 @@ doble_initial:
# --------------------------
# Selbst implementiertes Programm bauen
# --------------------------
# alle Objektdateien
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
# alle ausführbaren Dateien zu ausführbarem Programm linken
doble : main.o $(program_obj_files)
$(CC) $(FLAGS) $^ -o doble
$(program_obj_filesobj_files): %.o: %.c
# Regel Kompilieren allgemein
$(program_obj_files): %.o: %.c
$(CC) -c $(FLAGS) $^ -o $@
# --------------------------
# Unit Tests
# --------------------------
unitTests:
echo "needs to be implemented"
STACK_TEST_BIN = runStackTests
NUMBERS_TEST_BIN = runNumbersTests
BINARY_TEST_BIN = runBinaryTests
# --- Stack Tests ---
stackTests: stack.o test_stack.o
$(CC) $(FLAGS) -I$(unityfolder) -o $(STACK_TEST_BIN) stack.o test_stack.o $(unityfolder)/unity.c
test_stack.o: test_stack.c
$(CC) $(FLAGS) -I$(unityfolder) -c test_stack.c -o test_stack.o
# --- Numbers Tests ---
numbersTests: numbers.o bintree.o stack.o test_numbers.o
$(CC) $(FLAGS) -I$(unityfolder) -o $(NUMBERS_TEST_BIN) numbers.o bintree.o stack.o test_numbers.o $(unityfolder)/unity.c
test_numbers.o: test_numbers.c
$(CC) $(FLAGS) -I$(unityfolder) -c test_numbers.c -o test_numbers.o
# --- Binary Tree Tests ---
binaryTests: bintree.o stack.o test_binary.o
$(CC) $(FLAGS) -I$(unityfolder) -o $(BINARY_TEST_BIN) bintree.o stack.o test_binary.o $(unityfolder)/unity.c
test_binary.o: test_binary.c
$(CC) $(FLAGS) -I$(unityfolder) -c test_binary.c -o test_binary.o
# --------------------------
# Clean

103
numbers.c
View File

@ -1,26 +1,91 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "numbers.h"
#include "bintree.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
//TODO: getDuplicate und createNumbers implementieren
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
* 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. */
// 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)
{
int compareUnsignedInt(const void *a, const void *b) {
unsigned int x = *(unsigned int *)a;
unsigned int y = *(unsigned int *)b;
if (x < y)
return -1;
if (x > y)
return 1;
return 0;
}
// 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)
{
// TODO: getDuplicate und createNumbers implementieren
/**Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an
* Zufallszahlen. 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. */
}
// 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)
return NULL;
unsigned int *arr = malloc(sizeof(unsigned int) * len);
if (!arr)
return NULL;
TreeNode *root = NULL;
srand((unsigned int)time(NULL));
for (unsigned int i = 0; i < len - 1; i++) {
unsigned int num;
int isDuplicate;
do {
num = (rand() % (2 * len)) + 1;
isDuplicate = 0;
root = addToTree(root, &num, sizeof(unsigned int), compareUnsignedInt,
&isDuplicate);
} while (isDuplicate); // nur akzeptieren, wenn eindeutig
arr[i] = num;
}
// Jetzt gezielt EIN Duplikat erzeugen
unsigned int duplicateIndex = rand() % (len - 1);
arr[len - 1] = arr[duplicateIndex];
clearTree(root);
return arr;
}
// 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) {
if (!numbers || len < 2)
return 0;
unsigned int *copy = malloc(sizeof(unsigned int) * len);
if (!copy)
return 0;
memcpy(copy, numbers, sizeof(unsigned int) * len);
// Sortierung
qsort(copy, len, sizeof(unsigned int), compareUnsignedInt);
// Duplikat finden: zwei gleiche nebeneinander
unsigned int duplicate = 0;
for (unsigned int i = 0; i < len - 1; i++) {
if (copy[i] == copy[i + 1]) {
duplicate = copy[i];
break;
}
}
free(copy);
return duplicate;
}

View File

@ -1,6 +1,8 @@
#ifndef NUMBERS_H
#define NUMBERS_H
int compareUnsignedInt(const void *a, const void *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.

BIN
runTests.exe Normal file

Binary file not shown.

101
stack.c
View File

@ -1,33 +1,100 @@
#include <stdlib.h>
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
//TODO: grundlegende Stackfunktionen implementieren:
/*typedef struct {
void *data;
struct StackNode *next;
struct StackNode *prev;
} StackNode;*/
// TODO: grundlegende Stackfunktionen implementieren:
/* * `push`: legt ein Element oben auf den Stack,
* `pop`: entfernt das oberste Element,
* `top`: liefert das oberste Element zurück,
* `clearStack`: gibt den gesamten Speicher frei. */
* `pop`: entfernt das oberste Element,
* `top`: liefert das oberste Element zurück,
* `clearStack`: gibt den gesamten Speicher frei. */
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data)
{
// [A] -> [B] -> [C] -> NULL
// stack -> stack.next
// Funktion zum erstellen neuer nodes
StackNode *createNode(void *data) {
// Speicher reservieren
StackNode *node = malloc(sizeof(StackNode));
// Speicher konnte nicht reserviert werden
if (node == NULL)
return NULL;
node->data = data;
node->next = NULL;
node->prev = NULL;
return node;
}
// 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)
{
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data) {
StackNode *newNode = createNode(data);
// Fehler beim Reservieren des Speichers, stack wird unverändert zurückgegeben
if (newNode == NULL) {
return stack;
}
// der aktuelle Kopf wird der nächste Node
newNode->next = stack;
// bisheriger Kopf bekommt Pointer auf oberstes Element
if (stack != NULL) {
stack->prev = newNode;
}
return newNode; // neuer Kopf wird zurückgegeben
}
// 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) {
// Stack ohne Elemente
if (stack == NULL)
return NULL;
// Element unter Kopf wird als nextNode gespeichert
StackNode *nextNode = stack->next;
if (nextNode != NULL) {
nextNode->prev = NULL; // der Zeiger zum Kopf wird auf NULL gesetzt
}
free(stack);
stack = NULL; // Speicher des Kopfes freigeben
return nextNode; // neuen Kopf zurückgeben
}
// Returns the data of the top element.
void *top(StackNode *stack)
{
void *top(StackNode *stack) {
// wenn stack leer ist, wird NULL zurückgegeben
// Zeiger auf Daten des obersten Elements
return stack ? stack->data : NULL;
}
// Clears stack and releases all memory.
void clearStack(StackNode *stack)
{
void clearStack(StackNode **stack) { // Zeiger auf den Zeiger auf den Stackkopf
// verändert den Zeiger selbst, mit *stack lokale Kopie
// im Aufruf &stack verwenden
while (*stack != NULL) {
(*stack)->prev = NULL; // späteren Pointerzugriff verhindern
StackNode *next = (*stack)->next; // nächstes Element speichern
(*stack)->next = NULL; // späteren Pointerzugriff verhindern
free(*stack); // aktuelles Element freigeben
*stack = next; // Zeiger auf nächsten Knoten setzen
}
}

24
stack.h
View File

@ -1,25 +1,35 @@
#ifndef STACK_H
#define STACK_H
/* A stack is a special type of queue which uses the LIFO (last in, first out) principle.
This means that with each new element all other elements are pushed deeper into the stack.
The latest element is taken from the stack. */
/* A stack is a special type of queue which uses the LIFO (last in, first out)
principle. This means that with each new element all other elements are pushed
deeper into the stack. The latest element is taken from the stack. */
#include <stdlib.h>
//TODO: passenden Datentyp als struct anlegen
// TODO: passenden Datentyp als struct anlegen
typedef struct StackNode {
void *data;
struct StackNode *next;
struct StackNode *prev;
} StackNode;
StackNode *createNode(void *data);
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data);
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
// freed by caller.)
// 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);
// Returns the data of the top element.
void *top(StackNode *stack);
// Clears stack and releases all memory.
void clearStack(StackNode *stack);
void clearStack(StackNode **stack);
#endif

105
test_binary.c Normal file
View File

@ -0,0 +1,105 @@
#include "unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bintree.h"
int compareUnsignedInt(const void *a, const void *b) {
unsigned int x = *(unsigned int *)a;
unsigned int y = *(unsigned int *)b;
if (x < y)
return -1;
if (x > y)
return 1;
return 0;
}
TreeNode *root = NULL;
void setUp(void) {
root = NULL; // vor jedem Test leeren
}
void tearDown(void) { clearTree(root); }
// Test, ob addToTree Knoten korrekt hinzufügt
void test_addToTree_basic(void) {
int isDup;
unsigned int val = 10;
root = addToTree(root, &val, sizeof(val), compareUnsignedInt, &isDup);
TEST_ASSERT_NOT_NULL(root);
TEST_ASSERT_EQUAL_UINT(10, *(unsigned int *)root->data);
TEST_ASSERT_EQUAL_INT(0, isDup);
TEST_ASSERT_EQUAL_UINT(1, treeSize(root));
}
// Test, dass Duplikate erkannt werden
void test_addToTree_duplicate(void) {
int isDup;
unsigned int val1 = 10, val2 = 10;
root = addToTree(root, &val1, sizeof(val1), compareUnsignedInt, &isDup);
TEST_ASSERT_EQUAL_INT(0, isDup);
root = addToTree(root, &val2, sizeof(val2), compareUnsignedInt, &isDup);
TEST_ASSERT_EQUAL_INT(1, isDup);
TEST_ASSERT_EQUAL_UINT(1, treeSize(root)); // Duplikate nicht hinzufügen
}
// Test nextTreeData Traversierung
void test_nextTreeData_in_order(void) {
unsigned int values[] = {20, 10, 30};
int isDup;
for (int i = 0; i < 3; i++) {
root = addToTree(root, &values[i], sizeof(values[i]), compareUnsignedInt,
&isDup);
}
unsigned int expected[] = {10, 20, 30};
int idx = 0;
void *data;
// **Neue Iteration starten**
data = nextTreeData(root);
while (data != NULL) {
TEST_ASSERT_EQUAL_UINT(expected[idx], *(unsigned int *)data);
idx++;
data = nextTreeData(NULL); // weitere Elemente abrufen
}
TEST_ASSERT_EQUAL_INT(3, idx); // alle 3 Knoten besucht
}
// Test clearTree gibt Speicher frei
void test_clearTree(void) {
unsigned int val = 42;
int isDup;
root = addToTree(root, &val, sizeof(val), compareUnsignedInt, &isDup);
clearTree(root);
root = NULL; // clearTree löscht nicht die root-Variable selbst
TEST_ASSERT_NULL(root);
}
// Test treeSize zählt korrekt
void test_treeSize(void) {
unsigned int vals[] = {10, 20, 5};
int isDup;
for (int i = 0; i < 3; i++) {
root =
addToTree(root, &vals[i], sizeof(vals[i]), compareUnsignedInt, &isDup);
}
TEST_ASSERT_EQUAL_UINT(3, treeSize(root));
}
int main(void) {
UNITY_BEGIN();
printf(
"\n------------------------binarytree test------------------------\n\n");
RUN_TEST(test_addToTree_basic);
RUN_TEST(test_addToTree_duplicate);
RUN_TEST(test_nextTreeData_in_order);
RUN_TEST(test_clearTree);
RUN_TEST(test_treeSize);
return UNITY_END();
}

61
test_numbers.c Normal file
View File

@ -0,0 +1,61 @@
#include "unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "numbers.h"
#define TEST_ARRAY_LEN 100
void test_createNumbers_length(void) {
unsigned int *arr = createNumbers(TEST_ARRAY_LEN);
TEST_ASSERT_NOT_NULL(arr);
free(arr);
}
void test_createNumbers_single_duplicate(void) {
unsigned int *arr = createNumbers(TEST_ARRAY_LEN);
TEST_ASSERT_NOT_NULL(arr);
unsigned int duplicate = getDuplicate(arr, TEST_ARRAY_LEN);
TEST_ASSERT_TRUE(duplicate > 0);
unsigned int count = 0;
for (unsigned int i = 0; i < TEST_ARRAY_LEN; i++) {
if (arr[i] == duplicate) {
count++;
}
}
TEST_ASSERT_EQUAL_UINT(2, count);
free(arr);
}
void test_getDuplicate_manual_array(void) {
unsigned int numbers[5] = {10, 20, 30, 40, 20};
unsigned int dup = getDuplicate(numbers, 5);
TEST_ASSERT_EQUAL_UINT(20, dup);
}
void test_getDuplicate_invalid_input(void) {
TEST_ASSERT_EQUAL_UINT(0, getDuplicate(NULL, 5));
unsigned int arr[1] = {42};
TEST_ASSERT_EQUAL_UINT(0, getDuplicate(arr, 1));
}
void setUp(void) {}
void tearDown(void) {}
int main(void) {
UNITY_BEGIN();
printf("\n------------------------numbers test------------------------\n\n");
RUN_TEST(test_createNumbers_length);
RUN_TEST(test_createNumbers_single_duplicate);
RUN_TEST(test_getDuplicate_manual_array);
RUN_TEST(test_getDuplicate_invalid_input);
return UNITY_END();
}

144
test_stack.c Normal file
View File

@ -0,0 +1,144 @@
#include "unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
// StackNode *createNode(void *data) testen
void test_createNode(void) {
int testInt = 26;
StackNode *testNode = createNode(&testInt); // Adresse des testInts
TEST_ASSERT_NOT_NULL(
testNode); // Speicher konnte reserviert werden, malloc ist nicht NULL
TEST_ASSERT_EQUAL_PTR(&testInt, testNode->data); // data pointer gesetzt
TEST_ASSERT_NULL(testNode->next); // vorheriger und nächster Eintrag NULL
TEST_ASSERT_NULL(testNode->prev);
free(testNode); // Speicher freigeben
}
// StackNode *push(StackNode *stack, void *data) testen
void test_pushDataToStack(void) {
int testInts[] = {27, 28};
StackNode *testStack = NULL; // leeren testStack initialisieren
testStack =
push(testStack, &testInts[0]); // leerer Stack mit Adresse des testInts
TEST_ASSERT_NOT_NULL(testStack); // im Fehlerfall wird testStack unverändert
// zurückgegeben -> bei Fehler NULL
TEST_ASSERT_EQUAL_PTR(&testInts[0], testStack->data); // data pointer gesetzt
TEST_ASSERT_NULL(testStack->next); // vorheriger und nächster pointer auf NULL
// gesetzt, da es nur einen Knoten gibt
TEST_ASSERT_NULL(testStack->prev);
// zweiter Push
StackNode *oldHead = testStack; // bisherigen head speichern
testStack = push(testStack, &testInts[1]);
TEST_ASSERT_NOT_NULL(testStack);
TEST_ASSERT_NOT_EQUAL(
oldHead,
testStack); // bei malloc Fehler wird der head unverändert zurückgegeben
TEST_ASSERT_EQUAL_PTR(&testInts[0],
oldHead->data); // data pointer wurden richtig gesetzt
TEST_ASSERT_EQUAL_PTR(&testInts[1], testStack->data);
// richtige Verkettung: NULL <- testStack -> testStack->next -> oldHead ->
// NULL
TEST_ASSERT_EQUAL_PTR(oldHead, testStack->next);
TEST_ASSERT_EQUAL_PTR(testStack, oldHead->prev);
TEST_ASSERT_NULL(testStack->prev);
// Speicherfreigabe
testStack->next = NULL; // pointer ungültig machen, damit nicht ausversehen
// später aufgerufen
oldHead->prev = NULL;
free(oldHead);
free(testStack);
}
void test_deleteTopElement(void) {
int testInts[] = {10, 20, 30};
StackNode *stack = NULL;
for (int i = 0; i < 3;
i++) { // Stack mit drei Elementen, oberestes Element mit data 30
stack = push(stack, &testInts[i]);
}
TEST_ASSERT_EQUAL_PTR(&testInts[2], stack->data); // oberstes Element ist 30
stack = pop(stack); // oberstes Element löschen
TEST_ASSERT_EQUAL_PTR(&testInts[1], stack->data);
TEST_ASSERT_NULL(
stack->prev); // pointer zum alten head wurde auf NULL gesetzt
stack = pop(stack);
TEST_ASSERT_EQUAL_PTR(&testInts[0], stack->data);
TEST_ASSERT_NULL(stack->prev);
stack = pop(stack); // bei leerem Stack wird NULL zurückgegeben
TEST_ASSERT_NULL(stack);
}
void test_returnData(void) {
int testInts[] = {10, 20, 30};
StackNode *stack = NULL;
for (int i = 0; i < 3; i++) {
stack = push(stack, &testInts[i]);
}
TEST_ASSERT_EQUAL_PTR(&testInts[2],
top(stack)); // top gibt richtige Adresse zurück
stack = pop(stack); // oberstes Element löschen
TEST_ASSERT_EQUAL_PTR(&testInts[1], top(stack));
stack = pop(stack);
TEST_ASSERT_EQUAL_PTR(&testInts[0], top(stack));
stack = pop(stack); // bei leerem Stack wird NULL zurückgegeben
TEST_ASSERT_NULL(stack);
}
void test_clearStack(void) {
int testInts[] = {1, 2, 3, 4, 5};
StackNode *stack = NULL;
for (int i = 0; i < 5; i++) {
stack = push(stack, &testInts[i]);
}
//printf("testints: %d,%d,%d,%d,%d",testInts[0],testInts[1],testInts[2],testInts[3],testInts[4]);
clearStack(&stack);
TEST_ASSERT_NULL(stack);
}
void setUp(void) {}
void tearDown(void) {}
int main(void) {
UNITY_BEGIN();
printf("\n------------------------stack test------------------------\n\n");
RUN_TEST(test_createNode);
RUN_TEST(test_pushDataToStack);
RUN_TEST(test_deleteTopElement);
RUN_TEST(test_returnData);
RUN_TEST(test_clearStack);
return UNITY_END();
}