Compare commits

..

7 Commits

Author SHA1 Message Date
e884522b31 Testname geaendert 2025-12-11 16:25:54 +01:00
d42a9e09e1 Makefile angepasst 2025-12-10 19:06:28 +01:00
1a5b7cb025 pop-Funktion angepasst, erfolgreich getestet 2025-12-10 09:54:54 +01:00
2dc724e065 Test Stack geschrieben 2025-12-06 12:04:24 +01:00
127c7aa8e7 stack angepasst, test_stack.c hinzugefuegt 2025-12-05 09:29:15 +01:00
silvana884
8c0ff19529 Fehler bei stack geandert 2025-12-05 08:46:46 +01:00
silvana884
b5e5a8052f Test 2025-12-03 14:20:04 +01:00
25 changed files with 21 additions and 540 deletions

View File

@ -1,145 +0,0 @@
#include "unity.h"
#include <stdlib.h>
#include "bintree.h"
static int compare(const void *a, const void *b)
{
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); // a und b werden in int konvertiert und deren Werte miteinander verglichen
// returns 1 for a>b or -1 for a<b
// in bintree.c wird ueberprueft, ob compare eine positive oder eine negative Zahl zurueckgibt,
// wenn a groeßer b, positiv und dann wird links nach Teilbauemen gesucht
}
void setUp() {}
void tearDown() {}
//Adds a single element to the tree
void test_add_single_element_to_Tree()
{
TreeNode *root = NULL;
int value = 5;
int duplicate = -1;
root = addToTree(root, &value, sizeof(int), compare, &duplicate);
TEST_ASSERT_NOT_NULL(root); //uberprueft, ob root dem Tree hinzugefuegt werden konnte
TEST_ASSERT_EQUAL_INT(5, *(int*)root->data); //ueberprueft, ob der Wert fuer data richtig uebernommen wurde
TEST_ASSERT_EQUAL_INT(0, duplicate); //ueberprueft, ob isDuplicate 0 gesetzt wurde (neue Knoten -> isDuplicate sollte 0 sein)
clearTree(root);
}
//Adds multiplie elements to a tree
void test_add_multiple_elements_to_Tree()
{
TreeNode *root = NULL;
int value[] = {2, 5, 7, 9};
int duplicate = -1;
for(int j = 0; j < 4; ++j)
{
root = addToTree(root, &value[j], sizeof(int), compare, &duplicate); //Duplikate nicht erlaubt
}
TEST_ASSERT_EQUAL_INT(4, treeSize(root));
clearTree(root);
}
//Detects the size of a tree
void test_detect_empty_size()
{
TEST_ASSERT_EQUAL_INT(0, treeSize(NULL));
}
//checks, wether size of tree is correctly determined and wether clearTree() works
// Test: Duplikate nicht erlaubt (isDuplicate != NULL)
void test_detect_size() {
TreeNode *root = NULL;
int values[] = {1, 3, 1, 4, 5, 6, 7, 5, 9, 10};
int duplicate = 0; // wird pro Einfügen gesetzt
for (int j = 0; j < 10; ++j) {
root = addToTree(root, &values[j], sizeof(int), compare, &duplicate);
if (duplicate) {
// Ist der Wert schon eingefuegt? Also gibt es schon ein Duplikat?
TEST_ASSERT_TRUE(duplicate == 1);
}
duplicate = 0; // zurücksetzen für nächstes Einfügen
}
// Prüfen der Baumgroeße ohne Duplikate
TEST_ASSERT_EQUAL_INT(8, treeSize(root));
clearTree(root);
}
// Test: Duplikate erlaubt (isDuplicate == NULL)
void test_add_multiplie_elements_one_dup() {
TreeNode *root = NULL;
int values[] = {1, 3, 1, 4, 5, 6, 7, 5, 9, 10};
for (int j = 0; j < 10; ++j) {
root = addToTree(root, &values[j], sizeof(int), compare, NULL);
}
// Alle Werte inklusive Duplikate
TEST_ASSERT_EQUAL_INT(10, treeSize(root));
clearTree(root);
}
// Hilfsfunktion: rekursive Inorder-Prüfung
void inorderCheck(TreeNode *node, int expected[], int *idx) {
if (node == NULL) return;
// Linken Teilbaum prüfen
inorderCheck(node->left, expected, idx);
// Aktuelles Element prüfen -> wenn das aktuelle Element gefunden wurde, wird naechstes gesucht
TEST_ASSERT_EQUAL_INT(expected[*idx], *(int*)node->data);
(*idx)++;
// Rechten Teilbaum prüfen
inorderCheck(node->right, expected, idx);
}
//Traverses the tree inorder to check wether nextTreeData works
void test_inorder() {
TreeNode *root = NULL;
int values[] = {5, 3, 7, 2, 4, 6, 8};
// Baum füllen
for (int i = 0; i < 7; i++) {
root = addToTree(root, &values[i], sizeof(int), compare, NULL);
}
// Erwartete Inorder-Reihenfolge
int expected[] = {2,3,4,5,6,7,8};
int idx = 0;
//rekursives Pruefen der Eintraege
inorderCheck(root, expected, &idx);
// Alle Einträge geprüft?
TEST_ASSERT_EQUAL_INT(7, idx);
clearTree(root);
}
int main()
{
UNITY_BEGIN();
RUN_TEST(test_add_single_element_to_Tree);
RUN_TEST(test_add_multiple_elements_to_Tree);
RUN_TEST(test_add_multiplie_elements_one_dup);
RUN_TEST(test_detect_empty_size);
RUN_TEST(test_detect_size);
RUN_TEST(test_inorder);
return UNITY_END();
}

View File

@ -14,7 +14,7 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
{ {
if(data!= NULL && dataSize > 0) if(data!= NULL && dataSize > 0)
{ {
if(root == NULL) //Abbruchbedingung: Keine Wurzel vorhanden, deshalb fuegen wir hier einen neuen Knote ein if(root == NULL) //Abbruchbedingung: Keine Wurzel vorhanden, deshalb fügen wir hier einen neuen Knote ein
{ {
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode)); TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
if(newNode == NULL) if(newNode == NULL)
@ -31,7 +31,7 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
newNode->left = NULL; newNode->left = NULL;
newNode->right = NULL; newNode->right = NULL;
if(isDuplicate!= NULL) //wenn isDuplicate ungelich null, ignoriere duplikate und setze isDuplaicate 0 fuer neues Element if(isDuplicate!= NULL)
{ {
*isDuplicate = 0; *isDuplicate = 0;
} }
@ -48,7 +48,7 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
} }
else else
{ {
if (isDuplicate) { //Duplikate sollen ignoriert werden if (isDuplicate) {
*isDuplicate = 1; *isDuplicate = 1;
} }
else { else {
@ -66,42 +66,14 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
// push the top node and push all its left nodes. // push the top node and push all its left nodes.
void *nextTreeData(TreeNode *root) void *nextTreeData(TreeNode *root)
{ {
static StackNode *stack = NULL; if(root == NULL)
{
// 1) Falls neuer Baum übergeben wurde → Initialisieren
if (root != NULL)
{
// alten Stack leeren
while (stack != NULL)
stack = pop(stack);
// alle linken Knoten pushen
while (root != NULL) {
stack = push(stack, root);
root = root->left;
} }
} stackNode.top(root);
// 2) Wenn Stack leer → fertig
if (stack == NULL)
return NULL;
// 3) Top-Knoten holen
TreeNode *node = (TreeNode *)top(stack);
stack = pop(stack);
// 4) Wenn rechter Teilbaum existiert → alle linken Knoten pushen
TreeNode *right = node->right;
while (right != NULL) {
stack = push(stack, right);
right = right->left;
}
// 5) Daten zurückgeben
return node->data;
} }
// Releases all memory resources (including data copies). // Releases all memory resources (including data copies).
void clearTree(TreeNode *root) void clearTree(TreeNode *root)
{ {
@ -126,7 +98,7 @@ unsigned int treeSize(const TreeNode *root)
{ {
if(root == NULL) if(root == NULL)
{ {
return 0; return numNodes;
} }
return 1 + treeSize(root->left) + treeSize(root->right); //1, weil eine Wurzel gefunden wurde und dann immer plus eins fuer einen Teilbaum return 1 + treeSize(root->left) + treeSize(root->right); //1, weil eine Wurzel gefunden wurde und dann immer plus eins fuer einen Teilbaum

BIN
bintree.o

Binary file not shown.

BIN
doble.exe

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,2 @@
Silvana;9944 Silvana;9944
hannes;9910
silvana;9865
player2;4983
player1;3999 player1;3999

BIN
main.o

Binary file not shown.

View File

@ -53,7 +53,7 @@ test_numbers: numbers_no_tree.o bintree.o stack.o test_numbers.c $(unityfolder)/
test_stack: stack.o test_stack.c $(unityfolder)/unity.c test_stack: stack.o test_stack.c $(unityfolder)/unity.c
$(CC) $(FLAGS) -o runstackTests test_stack.c stack.o $(unityfolder)/unity.c $(CC) $(FLAGS) -o runtest_stack test_stack.c stack.o $(unityfolder)/unity.c
# -------------------------- # --------------------------
# Cleaning # Cleaning

View File

@ -14,91 +14,13 @@
// 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.
// Returns len random numbers between 1 and 2*len in random order,
// all different, except for exactly one duplicate (two entries the same).
// Uses your binary search tree implementation to check for duplicates while generating numbers.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "numbers.h"
#include "bintree.h"
int compareFct(const void *a, const void *b)
{
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); // a und b werden in int konvertiert und deren Werte miteinander verglichen
// returns 1 for a>b or -1 for a<b
// in bintree.c wird ueberprueft, ob compare eine positive oder eine negative Zahl zurueckgibt,
// wenn a groeßer b, positiv und dann wird links nach Teilbauemen gesucht
}
// Erzeugt len Zufallszahlen zwischen 1 und 2*len
// alle einzigartig, außer genau ein Duplikat
unsigned int *createNumbers(unsigned int len) unsigned int *createNumbers(unsigned int len)
{ {
if (len < 2)
return NULL;
srand((unsigned int)time(NULL));
unsigned int *numbers = malloc(len * sizeof(unsigned int));
if (!numbers)
return NULL;
TreeNode *root = NULL; // Baum anfänglich leer
unsigned int count = 0;
// Zufallszahlen generieren, bis das Array voll ist
while (count < len)
{
unsigned int random = (rand() % (2 * len)) + 1;
int duplicate = 0; // Anfangswert für Duplikat-Check
root = addToTree(root, &random, sizeof(random), compareFct, &duplicate);
if (root == NULL)
{
free(numbers);
return NULL;
}
if (!duplicate)
{
numbers[count++] = random;
}
// duplicate == 1 → Zahl existiert schon, neue Zahl generieren
}
// genau ein Duplikat erzeugen
unsigned int idx1 = rand() % len;
unsigned int idx2 = rand() % len;
while (idx2 == idx1)
idx2 = rand() % len;
numbers[idx2] = numbers[idx1];
// Baum wieder freigeben
clearTree(root);
return numbers;
} }
// Returns only the only number in numbers which is present twice. Returns zero on errors.
// findet die eine doppelte Zahl im Array
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{ {
if (!numbers || len < 2)
return 0;
for (unsigned int i = 0; i < len; i++)
{
for (unsigned int j = i + 1; j < len; j++)
{
if (numbers[i] == numbers[j])
return numbers[i];
}
}
return 0;
}
}

View File

@ -1,8 +1,6 @@
#ifndef NUMBERS_H #ifndef NUMBERS_H
#define NUMBERS_H #define NUMBERS_H
int compareFct(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 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.

BIN
numbers.o

Binary file not shown.

View File

@ -1,115 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "numbers.h"
#include "bintree.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. */
// -------------------------------------------------------------
// Vergleichsfunktion für qsort (Aufsteigend sortieren)
// -------------------------------------------------------------
static int compareUnsignedInt(const void *a, const void *b)
{
const unsigned int *ia = a;
const unsigned int *ib = b;
if (*ia < *ib) return -1;
if (*ia > *ib) return 1;
return 0;
}
// -------------------------------------------------------------
// createNumbers
// Erzeugt ein Array aus len Zufallszahlen (1..2*len), alle verschieden.
// Danach wird genau EIN zufälliger Eintrag dupliziert.
// Parameter: len = Anzahl der gewünschten Zufallszahlen
// Rückgabe: Pointer auf das erzeugte Array
// -------------------------------------------------------------
unsigned int *createNumbers(unsigned int len)
{
if (len < 2)
return NULL;
srand(time(NULL));
unsigned int *numbers = malloc(len * sizeof(unsigned int));
if (!numbers)
return NULL;
unsigned int count = 0;
// alle Werte verschieden erzeugen
while (count < len)
{
unsigned int value = (rand() % (2 * len)) + 1;
// Duplikatsprüfung
int exists = 0;
for (unsigned int i = 0; i < count; i++) {
if (numbers[i] == value) {
exists = 1;
break;
}
}
if (!exists)
numbers[count++] = value;
}
// EIN Duplikat erzeugen
unsigned int i1 = rand() % len;
unsigned int i2 = rand() % len;
while (i2 == i1)
i2 = rand() % len;
numbers[i2] = numbers[i1];
return numbers;
}
// -------------------------------------------------------------
// getDuplicate
// Findet die einzige Zahl, die im Array zweimal vorkommt.
// Sortiert dazu eine Kopie des Arrays und vergleicht benachbarte Werte.
// Parameter: numbers = Array von Zufallszahlen
// len = Anzahl der Elemente
// Rückgabe: die doppelte Zahl oder 0 bei Fehler
// -------------------------------------------------------------
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
if (!numbers || len < 2)
return 0;
// Kopie erzeugen, damit das Original unverändert bleibt
unsigned int *copy = malloc(len * sizeof(unsigned int));
if (!copy)
return 0;
memcpy(copy, numbers, len * sizeof(unsigned int));
// Sortieren
qsort(copy, len, sizeof(unsigned int), compareUnsignedInt);
// benachbarte Elemente vergleichen
unsigned int duplicate = 0;
for (unsigned int i = 1; i < len; i++) {
if (copy[i] == copy[i - 1]) {
duplicate = copy[i];
break;
}
}
free(copy);
return duplicate;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
runtest_stack.exe Normal file

Binary file not shown.

12
stack.c
View File

@ -1,14 +1,20 @@
#include <stdlib.h> #include <stdlib.h>
#include "stack.h" #include "stack.h"
//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. */
// 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)
{ {
if (!data) if (!data)
{ {
return stack; //Nichts pushen return stack; //Nichts pushen
} }
//if(stack && data){
StackNode *t = (StackNode *)malloc(sizeof(StackNode)); StackNode *t = (StackNode *)malloc(sizeof(StackNode));
if(!t) if(!t)
{ {
@ -17,7 +23,7 @@ StackNode *push(StackNode *stack, void *data)
t->next = stack; t->next = stack;
t->data = data; t->data = data;
return t; //Gibt den ersten StackNode des Stacks zurueck return t; //Gibt den ersten StackNode des Stacks zurueck
//}
return NULL; return NULL;
} }

View File

@ -8,12 +8,11 @@ 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 Node{ typedef struct StackNode {
void* data; void* data;
struct Node *next; struct StackNode *next;
}StackNode; }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);

BIN
stack.o

Binary file not shown.

View File

@ -1,153 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "numbers.h"
// -------------------------------------------------------------
// Hilfsfunktion: zählt, wie oft ein Wert im Array vorkommt
// -------------------------------------------------------------
static unsigned int countOccurrences(const unsigned int *arr, unsigned int len, unsigned int value)
{
unsigned int count = 0;
for (unsigned int i = 0; i < len; i++)
if (arr[i] == value)
count++;
return count;
}
// -------------------------------------------------------------
// Test 1: Array wird korrekt erzeugt (nicht NULL)
// -------------------------------------------------------------
void test_createNumbersReturnsNotNull(void)
{
unsigned int len = 20;
unsigned int *numbers = createNumbers(len);
TEST_ASSERT_NOT_NULL(numbers);
free(numbers);
}
// -------------------------------------------------------------
// Test 2: Alle Zahlen liegen im erlaubten Bereich (1..2*len)
// -------------------------------------------------------------
void test_numbersAreInCorrectRange(void)
{
unsigned int len = 50;
unsigned int *numbers = createNumbers(len);
TEST_ASSERT_NOT_NULL(numbers);
for (unsigned int i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(numbers[i] >= 1);
TEST_ASSERT_TRUE(numbers[i] <= 2 * len);
}
free(numbers);
}
// -------------------------------------------------------------
// Test 3: Es gibt GENAU EIN Duplikat
// -------------------------------------------------------------
void test_exactlyOneDuplicateExists(void)
{
unsigned int len = 80;
unsigned int *numbers = createNumbers(len);
TEST_ASSERT_NOT_NULL(numbers);
unsigned int duplicatesFound = 0;
for (unsigned int i = 0; i < len; i++)
{
unsigned int occurrences = countOccurrences(numbers, len, numbers[i]);
if (occurrences == 2)
duplicatesFound++;
}
// Da das Duplikat an zwei Positionen vorkommt,
// erwarten wir duplicatesFound == 2
TEST_ASSERT_EQUAL_UINT(2, duplicatesFound);
free(numbers);
}
// -------------------------------------------------------------
// Test 4: getDuplicate() findet die richtige doppelte Zahl
// -------------------------------------------------------------
void test_getDuplicateFindsCorrectValue(void)
{
unsigned int len = 100;
unsigned int *numbers = createNumbers(len);
TEST_ASSERT_NOT_NULL(numbers);
unsigned int duplicate = getDuplicate(numbers, len);
TEST_ASSERT_TRUE(duplicate >= 1);
TEST_ASSERT_TRUE(duplicate <= 2 * len);
TEST_ASSERT_EQUAL_UINT(2, countOccurrences(numbers, len, duplicate));
free(numbers);
}
// -------------------------------------------------------------
// Test 5: createNumbers() erzeugt len Elemente
// -------------------------------------------------------------
void test_arrayLengthIsCorrect(void)
{
unsigned int len = 30;
unsigned int *numbers = createNumbers(len);
TEST_ASSERT_NOT_NULL(numbers);
// Unity-Funktion prüft nicht direkt Länge, aber wir können checken,
// ob Zugriff auf alle Elemente möglich ist (Segfault würde Test crashen).
for (unsigned int i = 0; i < len; i++)
TEST_ASSERT_TRUE(numbers[i] >= 1);
free(numbers);
}
// -------------------------------------------------------------
// Leere setUp/tearDown
// -------------------------------------------------------------
void setUp(void) {}
void tearDown(void) {}
// -------------------------------------------------------------
// Hauptprogramm für Unity-Tests
// -------------------------------------------------------------
int main(void)
{
UNITY_BEGIN();
printf("\n============================\nNumbers tests\n============================\n");
RUN_TEST(test_createNumbersReturnsNotNull);
RUN_TEST(test_numbersAreInCorrectRange);
RUN_TEST(test_exactlyOneDuplicateExists);
RUN_TEST(test_getDuplicateFindsCorrectValue);
RUN_TEST(test_arrayLengthIsCorrect);
return UNITY_END();
}

BIN
test_stack.exe Normal file

Binary file not shown.

BIN
timer.o

Binary file not shown.