Template
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c07156e16 | ||
|
|
d25dfd669b | ||
|
|
a3f8aedb26 | ||
|
|
1ad200b828 | ||
|
|
31feb026d3 | ||
|
|
ad395ccf66 | ||
|
|
4e9c4f2496 | ||
|
|
61618e00bf | ||
|
|
da5a1d9cba | ||
|
|
4825bbab43 | ||
|
|
95af97bef7 |
No files matched your search
-62
@@ -1,62 +0,0 @@
|
||||
# ---> C
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
Startcode/doble_initial
|
||||
Startcode/doble
|
||||
Startcode/unitTests
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# IDE folders
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
#include <string.h>
|
||||
#include "stack.h"
|
||||
#include "bintree.h"
|
||||
|
||||
//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. */
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Returns the number of entries in the tree given by root.
|
||||
unsigned int treeSize(const TreeNode *root)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
player1;3999
|
||||
@@ -1,26 +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. */
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#include <stdlib.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.
|
||||
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.)
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
#include <string.h>
|
||||
#include "stack.h"
|
||||
#include "bintree.h"
|
||||
|
||||
//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. */
|
||||
|
||||
// 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).
|
||||
|
||||
// Hilfsfunktion: neuen Knoten erstellen und Daten kopieren
|
||||
static TreeNode* createNode(const void* data, size_t dataSize)
|
||||
{
|
||||
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->data = malloc(dataSize);
|
||||
if (node->data == NULL)
|
||||
{
|
||||
free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(node->data, data, dataSize);
|
||||
// dataSize wird NICHT im struct gespeichert, da es nicht im Header ist
|
||||
node->left = NULL;
|
||||
node->right = NULL;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// Fügt eine Kopie der Daten in den Baum ein (rekursiv)
|
||||
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize,
|
||||
CompareFctType compareFct, int *isDuplicate)
|
||||
{
|
||||
// Basisfall: leerer Baum oder Blattknoten erreicht
|
||||
if (root == NULL)
|
||||
{
|
||||
// isDuplicate auf 0 setzen, wenn nicht NULL
|
||||
if (isDuplicate != NULL)
|
||||
{
|
||||
*isDuplicate = 0;
|
||||
}
|
||||
|
||||
return createNode(data, dataSize);
|
||||
}
|
||||
|
||||
// Daten vergleichen
|
||||
int result = compareFct(data, root->data);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
// Daten sind kleiner -> in linken Teilbaum einfügen
|
||||
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
|
||||
}
|
||||
else if (result > 0)
|
||||
{
|
||||
// Daten sind größer -> in rechten Teilbaum einfügen
|
||||
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
|
||||
}
|
||||
else
|
||||
{
|
||||
// result == 0 → Duplikat gefunden
|
||||
if (isDuplicate != NULL)
|
||||
{
|
||||
*isDuplicate = 1; // Duplikat, nicht einfügen
|
||||
}
|
||||
else
|
||||
{
|
||||
// Duplikate sind erlaubt -> in rechten Teilbaum einfügen
|
||||
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
// Statischer Stack für die Iterator-Funktion (wie bei strtok)
|
||||
static StackNode *iteratorStack = NULL;
|
||||
|
||||
// Iteriert über den Baum (In-Order-Traversierung mit Stack)
|
||||
// Funktioniert wie strtok: beim ersten Aufruf root übergeben, dann NULL
|
||||
void *nextTreeData(TreeNode *root)
|
||||
{
|
||||
// Wenn root != NULL: neuer Iterator-Durchlauf starten
|
||||
if (root != NULL)
|
||||
{
|
||||
// Alten Stack löschen, falls vorhanden
|
||||
clearStack(iteratorStack);
|
||||
iteratorStack = NULL;
|
||||
|
||||
// Alle linken Knoten auf den Stack pushen (bis zum kleinsten Element)
|
||||
TreeNode *current = root;
|
||||
while (current != NULL)
|
||||
{
|
||||
iteratorStack = push(iteratorStack, current);
|
||||
current = current->left;
|
||||
}
|
||||
}
|
||||
|
||||
// Wenn Stack leer ist, sind wir fertig
|
||||
if (iteratorStack == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Oberstes Element vom Stack holen
|
||||
TreeNode *node = (TreeNode *)top(iteratorStack);
|
||||
iteratorStack = pop(iteratorStack);
|
||||
|
||||
// Wenn der Knoten einen rechten Teilbaum hat,
|
||||
// alle linken Knoten des rechten Teilbaums auf den Stack pushen
|
||||
if (node->right != NULL)
|
||||
{
|
||||
TreeNode *current = node->right;
|
||||
while (current != NULL)
|
||||
{
|
||||
iteratorStack = push(iteratorStack, current);
|
||||
current = current->left;
|
||||
}
|
||||
}
|
||||
|
||||
// Daten des aktuellen Knotens zurückgeben
|
||||
return node->data;
|
||||
}
|
||||
|
||||
// Gibt den gesamten Baum frei (rekursiv, Post-Order)
|
||||
void clearTree(TreeNode *root)
|
||||
{
|
||||
if (root == NULL)
|
||||
{
|
||||
return; // Basisfall: leerer Teilbaum
|
||||
}
|
||||
|
||||
// Erst linken Teilbaum löschen
|
||||
clearTree(root->left);
|
||||
|
||||
// Dann rechten Teilbaum löschen
|
||||
clearTree(root->right);
|
||||
|
||||
// Dann Daten und Knoten selbst löschen
|
||||
free(root->data);
|
||||
|
||||
// Knoten selbst freigeben
|
||||
free(root);
|
||||
}
|
||||
|
||||
// Zählt die Knoten im Baum (rekursiv)
|
||||
unsigned int treeSize(const TreeNode *root)
|
||||
{
|
||||
if (root == NULL)
|
||||
{
|
||||
return 0; // Basisfall: leerer Teilbaum
|
||||
}
|
||||
|
||||
// Rekursiv: Größe = 1 (aktueller Knoten) + linker Teilbaum + rechter Teilbaum
|
||||
return 1 + treeSize(root->left) + treeSize(root->right);
|
||||
}
|
||||
@@ -7,9 +7,10 @@ typedef int (*CompareFctType)(const void *arg1, const void *arg2);
|
||||
|
||||
typedef struct node
|
||||
{
|
||||
void *data;
|
||||
struct node *left;
|
||||
struct node *right;
|
||||
void *data; // Zeiger auf die Daten
|
||||
size_t dataSize; // ← NEU: Größe der Daten
|
||||
struct node *left; // Linker Teilbaum
|
||||
struct node *right; // Rechter Teilbaum
|
||||
} TreeNode;
|
||||
|
||||
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,5 @@
|
||||
manu;9959
|
||||
manu;9949
|
||||
player2;9925
|
||||
manu;4983
|
||||
player1;3999
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -29,21 +29,22 @@ program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
|
||||
doble : main.o $(program_obj_files)
|
||||
$(CC) $(FLAGS) $^ -o doble
|
||||
|
||||
$(program_obj_files): %.o: %.c
|
||||
$(program_obj_filesobj_files): %.o: %.c
|
||||
$(CC) -c $(FLAGS) $^ -o $@
|
||||
|
||||
# --------------------------
|
||||
# Unit Tests
|
||||
# --------------------------
|
||||
unitTests:
|
||||
echo "needs to be implemented"
|
||||
$(CC) $(FLAGS) $^ -o test_stack test_stack.c stack.c -Wall && ./test_stack
|
||||
$(CC) $(FLAGS) $^ -o test_numbers test_numbers.c numbers.c bintree.c stack.c -Wall && ./test_numbers
|
||||
|
||||
# --------------------------
|
||||
# Clean
|
||||
# --------------------------
|
||||
clean:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
del /f *.o doble
|
||||
del /f *.o doble test_stack test_numbers
|
||||
else
|
||||
rm -f *.o doble
|
||||
rm -f *.o doble test_stack test_numbers
|
||||
endif
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,135 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "numbers.h"
|
||||
#include "bintree.h"
|
||||
|
||||
|
||||
// Vergleichsfunktion für unsigned int (für Binärbaum und qsort)
|
||||
static int compareUnsignedInt(const void *a, const void *b)
|
||||
{
|
||||
unsigned int valA = *(unsigned int *)a;
|
||||
unsigned int valB = *(unsigned int *)b;
|
||||
|
||||
if (valA < valB) return -1;
|
||||
if (valA > valB) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Erzeugt ein Array mit len eindeutigen Zufallszahlen zwischen 1 und 2*len
|
||||
// Verwendet Binärbaum zur Duplikatsvermeidung
|
||||
// Gibt dann eine zufällige Zahl doppelt zurück
|
||||
unsigned int *createNumbers(unsigned int len)
|
||||
{
|
||||
// Eingabevalidierung
|
||||
if (len == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Array allokieren
|
||||
unsigned int *numbers = (unsigned int *)malloc(len * sizeof(unsigned int));
|
||||
if (numbers == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Binärbaum zur Duplikatsprüfung erstellen
|
||||
TreeNode *tree = NULL;
|
||||
|
||||
// Zufallsgenerator initialisieren
|
||||
static int seedInitialized = 0;
|
||||
if (!seedInitialized)
|
||||
{
|
||||
srand(time(NULL));
|
||||
seedInitialized = 1;
|
||||
}
|
||||
|
||||
// Zufallszahlen zwischen 1 und 2*len generieren (keine Duplikate)
|
||||
unsigned int inserted = 0;
|
||||
while (inserted < len)
|
||||
{
|
||||
// Zufallszahl zwischen 1 und 2*len generieren
|
||||
unsigned int randomNum = (rand() % (2 * len)) + 1;
|
||||
|
||||
// In Baum einfügen und prüfen, ob Duplikat
|
||||
int isDuplicate = 0;
|
||||
tree = addToTree(tree, &randomNum, sizeof(unsigned int),
|
||||
compareUnsignedInt, &isDuplicate);
|
||||
|
||||
// Wenn kein Duplikat, ins Array einfügen
|
||||
if (!isDuplicate)
|
||||
{
|
||||
numbers[inserted] = randomNum;
|
||||
inserted++;
|
||||
}
|
||||
}
|
||||
|
||||
// Baum aufräumen
|
||||
clearTree(tree);
|
||||
|
||||
// Einen zufälligen Eintrag duplizieren
|
||||
// Wähle zwei verschiedene Indizes
|
||||
unsigned int sourceIndex = rand() % len;
|
||||
unsigned int targetIndex;
|
||||
|
||||
do
|
||||
{
|
||||
targetIndex = rand() % len;
|
||||
} while (targetIndex == sourceIndex);
|
||||
|
||||
// Kopiere Wert von source nach target (erzeugt Duplikat)
|
||||
numbers[targetIndex] = numbers[sourceIndex];
|
||||
|
||||
return numbers;
|
||||
}
|
||||
|
||||
// Findet das Duplikat durch Sortieren und Vergleich benachbarter Elemente
|
||||
// Gibt 0 bei Fehlern zurück
|
||||
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
||||
{
|
||||
// Eingabevalidierung
|
||||
if (numbers == NULL || len < 2)
|
||||
{
|
||||
return 0; // Fehler
|
||||
}
|
||||
|
||||
// Kopie des Arrays erstellen (um Original nicht zu verändern)
|
||||
unsigned int *sortedNumbers = (unsigned int *)malloc(len * sizeof(unsigned int));
|
||||
if (sortedNumbers == NULL)
|
||||
{
|
||||
return 0; // Speicherfehler
|
||||
}
|
||||
|
||||
// Array kopieren
|
||||
memcpy(sortedNumbers, numbers, len * sizeof(unsigned int));
|
||||
|
||||
// Array mit qsort sortieren
|
||||
qsort(sortedNumbers, len, sizeof(unsigned int), compareUnsignedInt);
|
||||
|
||||
// Benachbarte Elemente vergleichen, um Duplikat zu finden
|
||||
unsigned int duplicate = 0;
|
||||
for (unsigned int i = 0; i < len - 1; i++)
|
||||
{
|
||||
if (sortedNumbers[i] == sortedNumbers[i + 1])
|
||||
{
|
||||
duplicate = sortedNumbers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Aufräumen
|
||||
free(sortedNumbers);
|
||||
|
||||
return duplicate;
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,76 @@
|
||||
#include <stdlib.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.
|
||||
StackNode *push(StackNode *stack, void *data)
|
||||
{
|
||||
// Speicher für den neuen Knoten allokieren
|
||||
StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));
|
||||
|
||||
// Prüfen, ob die Allokierung erfolgreich war
|
||||
if (newNode == NULL)
|
||||
{
|
||||
return stack; // Unveränderter Stack bei Fehler
|
||||
}
|
||||
|
||||
// Neuen Knoten initialisieren
|
||||
newNode->data = data;
|
||||
newNode->next = stack; // Zeigt auf die aktuelle Spitze des Stacks
|
||||
|
||||
// Neuen Knoten als neue Spitze des Stacks zurückgeben
|
||||
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)
|
||||
{
|
||||
// Prüfen, ob der Stack leer ist
|
||||
if (stack == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Zeiger auf den nächsten Knoten speichern (wird zur neuen Spitze)
|
||||
StackNode *newTop = stack->next;
|
||||
|
||||
// Aktuellen obersten Knoten freigeben (aber NICHT die Daten - Verantwortung des Aufrufers)
|
||||
free(stack);
|
||||
|
||||
// Neue Spitze des Stacks zurückgeben
|
||||
return newTop;
|
||||
}
|
||||
|
||||
// Returns the data of the top element.
|
||||
void *top(StackNode *stack)
|
||||
{
|
||||
// Prüfen, ob der Stack leer ist
|
||||
if (stack == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Datenzeiger des obersten Knotens zurückgeben
|
||||
return stack->data;
|
||||
}
|
||||
|
||||
// Clears stack and releases all memory.
|
||||
void clearStack(StackNode *stack)
|
||||
{
|
||||
StackNode *current = stack;
|
||||
StackNode *next;
|
||||
|
||||
// Durch alle Knoten iterieren und freigeben
|
||||
while (current != NULL)
|
||||
{
|
||||
next = current->next; // Nächsten Knoten speichern
|
||||
free(current); // Aktuellen Knoten freigeben (aber NICHT die Daten)
|
||||
current = next; // Zum nächsten Knoten weitergehen
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,13 @@ The latest element is taken from the stack. */
|
||||
#include <stdlib.h>
|
||||
|
||||
//TODO: passenden Datentyp als struct anlegen
|
||||
typedef struct StackNode
|
||||
{
|
||||
void *data;
|
||||
struct StackNode *next;
|
||||
struct StackNode *prev;
|
||||
}StackNode;
|
||||
|
||||
|
||||
// Pushes data as pointer onto the stack.
|
||||
StackNode *push(StackNode *stack, void *data);
|
||||
@@ -0,0 +1,60 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "stack.h"
|
||||
#include "numbers.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("=== Test createNumbers & getDuplicate ===\n\n");
|
||||
|
||||
unsigned int len = 10;
|
||||
unsigned int *numbers = createNumbers(len);
|
||||
|
||||
if (numbers == NULL)
|
||||
{
|
||||
printf("Fehler: createNumbers() gab NULL zurück\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Generierte Zahlen: ");
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
printf("%u ", numbers[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
unsigned int duplicate = getDuplicate(numbers, len);
|
||||
|
||||
if (duplicate == 0)
|
||||
{
|
||||
printf("Fehler: Kein Duplikat gefunden\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Gefundenes Duplikat: %u\n", duplicate);
|
||||
|
||||
// Prüfen, ob es wirklich zweimal vorkommt
|
||||
int count = 0;
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
if (numbers[i] == duplicate)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
printf("Anzahl Vorkommen: %d\n", count);
|
||||
|
||||
if (count == 2)
|
||||
{
|
||||
printf("\n[PASSED] Test erfolgreich!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n[FAILED] Duplikat kommt %d mal vor (erwartet: 2)\n", count);
|
||||
}
|
||||
}
|
||||
|
||||
free(numbers);
|
||||
return 0;
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "stack.h"
|
||||
|
||||
// Hilfsfunktion: Gibt "PASSED" oder "FAILED" aus
|
||||
void printTestResult(const char *testName, int passed)
|
||||
{
|
||||
if (passed)
|
||||
{
|
||||
printf("[PASSED] %s\n", testName);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[FAILED] %s\n", testName);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 1: Leerer Stack
|
||||
void test_emptyStack()
|
||||
{
|
||||
StackNode *stack = NULL;
|
||||
|
||||
// Top auf leerem Stack sollte NULL zurückgeben
|
||||
void *result = top(stack);
|
||||
printTestResult("Test 1: top() auf leerem Stack", result == NULL);
|
||||
|
||||
// Pop auf leerem Stack sollte NULL zurückgeben
|
||||
stack = pop(stack);
|
||||
printTestResult("Test 1: pop() auf leerem Stack", stack == NULL);
|
||||
}
|
||||
|
||||
// Test 2: Push und Top
|
||||
void test_pushAndTop()
|
||||
{
|
||||
StackNode *stack = NULL;
|
||||
|
||||
// Integer-Werte allokieren
|
||||
int *val1 = (int *)malloc(sizeof(int));
|
||||
*val1 = 42;
|
||||
|
||||
// Wert auf den Stack legen
|
||||
stack = push(stack, val1);
|
||||
|
||||
// Obersten Wert abrufen
|
||||
int *topVal = (int *)top(stack);
|
||||
int passed = (topVal != NULL && *topVal == 42);
|
||||
printTestResult("Test 2: push() und top()", passed);
|
||||
|
||||
// Aufräumen
|
||||
free(val1);
|
||||
clearStack(stack);
|
||||
}
|
||||
|
||||
//Test 3 mehrmaliges pushen
|
||||
void test_multiplePush()
|
||||
{
|
||||
StackNode *stack = NULL;
|
||||
|
||||
//Speicher für Werte allokieren
|
||||
int *val1 = (int *) malloc(sizeof(int));
|
||||
int *val2 = (int *) malloc(sizeof(int));
|
||||
int *val3 = (int *) malloc(sizeof(int));
|
||||
|
||||
*val1 = 10;
|
||||
*val2 = 20;
|
||||
*val3 = 30;
|
||||
|
||||
//Testwerte auf den Stack legen
|
||||
stack = push(stack, val1);
|
||||
stack = push(stack, val2);
|
||||
stack = push(stack, val3);
|
||||
|
||||
// Oberster Wert sollte 30 sein (LIFO)
|
||||
int *topVal = (int *)top(stack);
|
||||
int passed = (topVal != NULL && *topVal == 30);
|
||||
printTestResult("Test 3: Mehrfache push() - LIFO-Prinzip", passed);
|
||||
|
||||
// Aufräumen
|
||||
free(val1);
|
||||
free(val2);
|
||||
free(val3);
|
||||
clearStack(stack);
|
||||
|
||||
}
|
||||
|
||||
// Test 4: Push und Pop
|
||||
void test_pushAndPop()
|
||||
{
|
||||
StackNode *stack = NULL;
|
||||
|
||||
// Drei Werte auf den Stack legen
|
||||
int *val1 = (int *)malloc(sizeof(int));
|
||||
int *val2 = (int *)malloc(sizeof(int));
|
||||
int *val3 = (int *)malloc(sizeof(int));
|
||||
|
||||
*val1 = 100;
|
||||
*val2 = 200;
|
||||
*val3 = 300;
|
||||
|
||||
stack = push(stack, val1);
|
||||
stack = push(stack, val2);
|
||||
stack = push(stack, val3);
|
||||
|
||||
// Oberster Wert: 300
|
||||
int *topVal1 = (int *)top(stack);
|
||||
int test1 = (topVal1 != NULL && *topVal1 == 300);
|
||||
|
||||
// Pop - neuer oberster Wert: 200
|
||||
stack = pop(stack);
|
||||
int *topVal2 = (int *)top(stack);
|
||||
int test2 = (topVal2 != NULL && *topVal2 == 200);
|
||||
|
||||
// Pop - neuer oberster Wert: 100
|
||||
stack = pop(stack);
|
||||
int *topVal3 = (int *)top(stack);
|
||||
int test3 = (topVal3 != NULL && *topVal3 == 100);
|
||||
|
||||
// Pop - Stack sollte leer sein
|
||||
stack = pop(stack);
|
||||
int test4 = (stack == NULL);
|
||||
|
||||
int passed = test1 && test2 && test3 && test4;
|
||||
printTestResult("Test 4: push() und pop() - Korrekte Reihenfolge", passed);
|
||||
|
||||
// Aufräumen
|
||||
free(val1);
|
||||
free(val2);
|
||||
free(val3);
|
||||
}
|
||||
|
||||
// Test 5: ClearStack
|
||||
void test_clearStack()
|
||||
{
|
||||
StackNode *stack = NULL;
|
||||
|
||||
// Mehrere Werte auf den Stack legen
|
||||
int *val1 = (int *)malloc(sizeof(int));
|
||||
int *val2 = (int *)malloc(sizeof(int));
|
||||
int *val3 = (int *)malloc(sizeof(int));
|
||||
int *val4 = (int *)malloc(sizeof(int));
|
||||
int *val5 = (int *)malloc(sizeof(int));
|
||||
|
||||
*val1 = 1;
|
||||
*val2 = 2;
|
||||
*val3 = 3;
|
||||
*val4 = 4;
|
||||
*val5 = 5;
|
||||
|
||||
stack = push(stack, val1);
|
||||
stack = push(stack, val2);
|
||||
stack = push(stack, val3);
|
||||
stack = push(stack, val4);
|
||||
stack = push(stack, val5);
|
||||
|
||||
// Stack löschen
|
||||
clearStack(stack);
|
||||
stack = NULL; // Nach clearStack ist der Stack leer
|
||||
|
||||
printTestResult("Test 5: clearStack() - Alle Knoten freigegeben", 1);
|
||||
|
||||
// Daten müssen manuell freigegeben werden (Verantwortung des Aufrufers)
|
||||
free(val1);
|
||||
free(val2);
|
||||
free(val3);
|
||||
free(val4);
|
||||
free(val5);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("=== Stack Unit-Tests ===\n\n");
|
||||
|
||||
test_emptyStack();
|
||||
test_pushAndTop();
|
||||
test_multiplePush();
|
||||
test_pushAndPop();
|
||||
/*test_clearStack();*/
|
||||
/*test_stressTest();*/
|
||||
|
||||
printf("\n=== Alle Tests abgeschlossen ===\n");
|
||||
printf("\nCode-Review: Speicherverwaltung\n");
|
||||
printf("--------------------------------\n");
|
||||
printf("✓ Aufrufer gibt Daten frei, Stack-Funktionen geben Knoten frei\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user