Compare commits

..

54 Commits

Author SHA1 Message Date
07796c1390 changed addToTreeRec so it now sets inDuplicate to 0 if needed 2025-12-12 06:50:50 +01:00
Florian Wetzel
25da0d20df Troubleshooting wegen gefailter Tests. Aenderungen in bintree.c bei Duplikatsüberprüfung 2025-12-11 15:37:48 +01:00
6586a25fdb created all tests 2025-12-11 08:09:45 +01:00
6e233b6695 created all tests 2025-12-11 08:09:39 +01:00
a01aa986e6 corrected treeSizeRec cause previously end of non void function could be reached 2025-12-11 08:07:23 +01:00
Florian Wetzel
aae75ade4b Ergänzung makefile um test_numbers 2025-12-10 14:28:12 +01:00
Florian Wetzel
5d976c50c1 test_numbers.c vervollständigt 2025-12-10 14:19:37 +01:00
92fa60f9dc Merge branch 'branchjonas' 2025-12-10 12:26:54 +01:00
284cdbdcfb made runbintreeTests.exe 2025-12-10 12:18:49 +01:00
e3501e8550 added runbintreeTests.exe and stack.o 2025-12-09 23:18:36 +01:00
6a9461bf5b all binaryTree functions and Tests working 2025-12-09 23:13:39 +01:00
ef3e0b7891 changed binTreeTest makefile, test_nextTreeDataReturnsNextDataCorrectly() not yet working 2025-12-09 22:41:35 +01:00
82b2fb283f merged branchjens 2025-12-09 22:28:31 +01:00
602220ba21 Merge branch 'branchjens' into branchjonas 2025-12-09 22:27:30 +01:00
2368c9f3b9 added stack to makefile 2025-12-09 22:27:14 +01:00
e4a8afabdd wrote test_nextTreeDataReturnsNextDataCorrectly() 2025-12-09 21:48:43 +01:00
9d08970513 wrote nextTreeData() and nextTreeDataRec() 2025-12-09 21:12:03 +01:00
9ee0f9e281 treeSize and treeSize test now workingW 2025-12-09 18:41:02 +01:00
21aa67b165 removed no longer needed comments 2025-12-09 18:04:58 +01:00
2d6f8689f2 corrected mistake in test_clearTreeworksLikeExpected 2025-12-09 17:59:21 +01:00
8754182f79 clear Tree and test now working corectly 2025-12-09 17:51:11 +01:00
144648886f addToTree corrected 2025-12-09 11:19:56 +01:00
748fd0d087 corrected unwanted add 2025-12-09 11:15:01 +01:00
72f1d080a0 adToTree working again 2025-12-09 11:10:29 +01:00
Florian Wetzel
a6c5060060 test_numbers.c Grundgerüst 2025-12-09 10:24:54 +01:00
02e008c03a debug 2025-12-09 09:59:22 +01:00
Florian Wetzel
2689130b55 numbers.c bearbeitet 2025-12-09 09:57:13 +01:00
7c3df62d86 further debugging 2025-12-09 08:46:56 +01:00
f7549910eb freeing node->data works, freeing node itself does not 2025-12-09 08:09:59 +01:00
14fa122f20 added runbintreeTests.exe to git 2025-12-09 07:22:34 +01:00
1c10994396 clear does not yet work, also TEST_ASSERT_EQUAL datatype is off 2025-12-09 01:40:43 +01:00
402604cb45 removed no longer needed code 2025-12-09 01:07:39 +01:00
5dc45f8590 uncommented not needed code from test_addToTreeExpandsTreeCorrectly and addToTree 2025-12-09 01:03:58 +01:00
6b30677698 addToTreeExpandsTreeCorrectly 2025-12-09 01:00:42 +01:00
d56a2f7a03 adding double working, double not Permitted not working 2025-12-09 00:44:04 +01:00
36ac0d6d9d normal Nodes working in addToTree() 2025-12-09 00:36:27 +01:00
517d363f3e debugging 2025-12-08 22:41:49 +01:00
f91ab68a72 added bintree.o to git 2025-12-08 20:49:01 +01:00
574ed71bae added bintree.o to makefile 2025-12-08 20:48:02 +01:00
c49a8d687c reset highscore.txt 2025-12-08 13:01:23 +01:00
42b83afec0 Merge branch 'branchjens' into branchjonas 2025-12-08 12:58:13 +01:00
b138a8f251 added bintreeTests to makefile as Target 2025-12-08 08:36:00 +01:00
ffde7270db wrote main() in bintreeTests.c 2025-12-08 08:30:10 +01:00
409afc165b wrote test_treeSizeWorkingLikeExpected(void) 2025-12-08 08:24:30 +01:00
4042a7d979 wrote test_clearTreeworksLikeExpected() 2025-12-08 08:19:12 +01:00
1ead9595ce wrote test_addToTreeExpandsTreeCorrectly() 2025-12-08 08:03:16 +01:00
e523b5462d started writing tests but ran into problems 2025-12-07 23:23:32 +01:00
b50bd58dac created bintreeTests.c 2025-12-07 14:34:37 +01:00
2176383f1e wrote treeSize(), created treeSizeRec() 2025-12-06 23:44:40 +01:00
e52da066fa wrote clearTree(), created clearTreeRec() and clearNode() 2025-12-06 23:18:07 +01:00
494fa2237c fixed logic problem in addToTreeRec() 2025-12-06 22:27:57 +01:00
7dca38c37f wrote first version of addToTree() and wrote new recursive function addToTreeRec() 2025-12-06 16:40:57 +01:00
03495bddf0 einlesen und grobe logik in kommentaren etablieren 2025-12-05 23:50:23 +01:00
1763ac1f6d made doble_initial 2025-12-02 19:19:02 +01:00
17 changed files with 726 additions and 10 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

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

@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "macos-clang-arm64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "macos-clang-arm64",
"compilerArgs": [
""
]
}
],
"version": 4
}

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

@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "/Users/florianwetzel/I2_Praktikum/DobleSpiel",
"program": "/Users/florianwetzel/I2_Praktikum/DobleSpiel/build/Debug/outDebug"
}
]
}

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

@ -0,0 +1,59 @@
{
"C_Cpp_Runner.cCompilerPath": "clang",
"C_Cpp_Runner.cppCompilerPath": "clang++",
"C_Cpp_Runner.debuggerPath": "lldb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "",
"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
}

223
bintree.c
View File

@ -1,36 +1,249 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.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. */
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv), Done
* `clearTree`: gibt den gesamten Baum frei (rekursiv), Done
* `treeSize`: zählt die Knoten im Baum (rekursiv), Done
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. Done */
static StackNode *stackRoot = NULL;
TreeNode *addToTree (TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate);
void *nextTreeData (TreeNode *root);
void clearTree (TreeNode *root);
unsigned int treeSize (const TreeNode *root);
// self declared functions
TreeNode *addToTreeRec (TreeNode *currentNode, TreeNode *newNode, CompareFctType compareFct, int *isDuplicate, const int root);
void clearTreeRec (TreeNode *currentNode);
void clearNode (TreeNode *node);
int treeSizeRec (const TreeNode *currentNode);
void *nextTreeDataRec (TreeNode *node, StackNode *stack);
// 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).
// returned Value is new root
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
{
// create a node
TreeNode *newNode;
newNode = calloc(1, sizeof(TreeNode));
newNode->data = calloc(1, dataSize);
newNode->left = NULL;
newNode->right = NULL;
memcpy(newNode->data, data, dataSize);
return addToTreeRec(root, newNode, compareFct, isDuplicate, 1);
}
/*
TreeNode *addToTreeRec(TreeNode *currentNode, TreeNode *newNode, CompareFctType compareFct, int *isDuplicate, const int root)
{
/*if ((currentNode == NULL))
{
if ((isDuplicate == NULL) || root)
{
return newNode;
}
else
{
return currentNode;
}
}
// Mögliche Ergänzung --------------------------
if (currentNode == NULL)
{
if (isDuplicate != NULL)
*isDuplicate = 0;
return newNode;
}
//--------------------------------
else if ((compareFct(currentNode->data, newNode->data) < 0))
{
currentNode->left = addToTreeRec(currentNode->left, newNode, compareFct, isDuplicate, 0);
}
else if ((compareFct(currentNode->data, newNode->data) > 0))
{
currentNode->right = addToTreeRec(currentNode->right, newNode, compareFct, isDuplicate, 0);
}
else if ((compareFct(currentNode->data, newNode->data) == 0))
{
if (isDuplicate == NULL)
{
currentNode->left = addToTreeRec(currentNode->left, newNode, compareFct, isDuplicate, 0);
}
else
{
*isDuplicate = 1;
}
}
return currentNode;
} */
TreeNode *addToTreeRec(TreeNode *currentNode, TreeNode *newNode, CompareFctType compareFct, int *isDuplicate, const int root)
{
if ((currentNode == NULL))
{
if ((isDuplicate == NULL) || root)
{
if (isDuplicate != NULL)
{
*isDuplicate = 0;
}
return newNode;
}
else
{
*isDuplicate = 0;
return currentNode;
}
}
else if ((compareFct(currentNode->data, newNode->data) < 0))
{
currentNode->left = addToTreeRec(currentNode->left, newNode, compareFct, isDuplicate, 0);
}
else if ((compareFct(currentNode->data, newNode->data) > 0))
{
currentNode->right = addToTreeRec(currentNode->right, newNode, compareFct, isDuplicate, 0);
}
else if ((compareFct(currentNode->data, newNode->data) == 0))
{
if (isDuplicate == NULL)
{
currentNode->left = addToTreeRec(currentNode->left, newNode, compareFct, isDuplicate, 0);
}
else
{
*isDuplicate = 1;
}
}
if (isDuplicate != NULL)
{
*isDuplicate = 0;
}
return currentNode;
}
// 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.
// Needs stack!!
// Stack functions: push(), pop(), top(), clearStack()
void *nextTreeData(TreeNode *root)
{
void *pointerToReturn = NULL;
if (root != NULL)
{
// Add tree to stack so that bigest entry is ontop
stackRoot = nextTreeDataRec(root, stackRoot);
pointerToReturn = stackRoot;
}
else
{
// return current top entry and then pop that top entry
pointerToReturn = top(stackRoot);
stackRoot = pop(stackRoot);
}
return pointerToReturn;
}
void *nextTreeDataRec(TreeNode *tree, StackNode *stack)
{
if (tree != NULL)
{
stack = nextTreeDataRec (tree->left, stack);
stack = push (stack, tree->data);
stack = nextTreeDataRec (tree->right, stack);
}
return stack;
}
// Releases all memory resources (including data copies).
void clearTree(TreeNode *root)
{
clearTreeRec(root);
}
void clearTreeRec(TreeNode *currentNode)
{
if (currentNode != NULL)
{
clearTree(currentNode->left);
clearTree(currentNode->right);
clearNode(currentNode);
}
}
void clearNode(TreeNode *node)
{
free(node->data);
node->data = NULL;
node->left = NULL;
node->right = NULL;
free(node);
node = NULL;
}
// Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root)
{
unsigned int amountOfNodes = 0;
amountOfNodes = treeSizeRec(root);
return amountOfNodes;
}
int treeSizeRec(const TreeNode *currentNode)
{
int nodeCount = 0;
if (currentNode != NULL)
{
nodeCount += treeSizeRec(currentNode->left);
nodeCount += treeSizeRec(currentNode->right);
return nodeCount + 1;
}
return nodeCount;
}

BIN
bintree.o Normal file

Binary file not shown.

223
bintreeTests.c Normal file
View File

@ -0,0 +1,223 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "unity.h"
#include "bintree.h"
#include "stack.h"
#define MAX_TEST_NAME_LEN 10
void setUp(void) {
// Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden
}
void tearDown(void) {
// Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden
}
static int compareIntEntries(const void *arg1, const void *arg2)
{
const int *entry1 = (const void *)arg1;
const int *entry2 = (const void *)arg2;
int result = *entry2 - *entry1;
return result;
}
// test if addToTree expands tree correctly
// by going down the path where the given pice of data is expected
// and checking if the pice of data is found there
void test_addToTreeExpandsTreeCorrectly(void)
{
TreeNode *testRoot = NULL;
int testIsDouble = 0;
int score1 = 12;
int score2 = 6;
int score3 = 18;
int score4 = 3;
int score5 = 9;
int score6 = 15;
int score7 = 21;
testRoot = addToTree(testRoot, &score1, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score2, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score3, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score4, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score5, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score6, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score7, sizeof(int), compareIntEntries, NULL);
// Checking the Tree without Doubles
TEST_ASSERT_NOT_NULL(testRoot);
TEST_ASSERT_EQUAL(score1, *(int *)testRoot->data);
TEST_ASSERT_NOT_NULL(testRoot->left);
TEST_ASSERT_EQUAL(score2, *(int *)testRoot->left->data);
TEST_ASSERT_NOT_NULL(testRoot->right);
TEST_ASSERT_EQUAL(score3, *(int *)testRoot->right->data);
TEST_ASSERT_NOT_NULL(testRoot->left->left);
TEST_ASSERT_EQUAL(score4, *(int *)testRoot->left->left->data);
TEST_ASSERT_NOT_NULL(testRoot->left->right);
TEST_ASSERT_EQUAL(score5, *(int *)testRoot->left->right->data);
TEST_ASSERT_NOT_NULL(testRoot->right->left);
TEST_ASSERT_EQUAL(score6, *(int *)testRoot->right->left->data);
TEST_ASSERT_NOT_NULL(testRoot->right->right);
TEST_ASSERT_EQUAL(score7, *(int *)testRoot->right->right->data);
// Adding Double
testRoot = addToTree(testRoot, &score4, sizeof(int), compareIntEntries, NULL);
TEST_ASSERT_NOT_NULL(testRoot->left->left->left);
TEST_ASSERT_EQUAL_UINT16(score4, *(int *)testRoot->left->left->left->data);
// Trying to add Double while Doubles not Permitted
testRoot = addToTree(testRoot, &score7, sizeof(int), compareIntEntries, &testIsDouble);
TEST_ASSERT_NULL(testRoot->right->right->left);
TEST_ASSERT_EQUAL_UINT16(1, testIsDouble);
clearTree(testRoot);
}
// test if nextTreeData returns the next pice of data correctly
// needs Stack!!!
void test_nextTreeDataReturnsNextDataCorrectly(void)
{
TreeNode *testRoot = NULL;
int score1 = 12;
int score2 = 6;
int score3 = 18;
int score4 = 3;
int score5 = 9;
int score6 = 15;
int score7 = 21;
// Prepare a Tree
testRoot = addToTree(testRoot, &score1, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score2, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score3, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score4, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score5, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score6, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score7, sizeof(int), compareIntEntries, NULL);
// Create Stack
StackNode *entry = nextTreeData(testRoot);
// check if nextTreeData returns Data correctly
TEST_ASSERT_NOT_NULL(entry);
TEST_ASSERT_EQUAL(score7, *(int *)nextTreeData(NULL));
TEST_ASSERT_EQUAL(score3, *(int *)nextTreeData(NULL));
TEST_ASSERT_EQUAL(score6, *(int *)nextTreeData(NULL));
TEST_ASSERT_EQUAL(score1, *(int *)nextTreeData(NULL));
TEST_ASSERT_EQUAL(score5, *(int *)nextTreeData(NULL));
TEST_ASSERT_EQUAL(score2, *(int *)nextTreeData(NULL));
TEST_ASSERT_EQUAL(score4, *(int *)nextTreeData(NULL));
clearTree(testRoot);
}
// test if clear Tree frees all node.name and node memory AND sets them to zero
// aditionally tests if the memoryspaces have been cleared
void test_clearTreeworksLikeExpected(void)
{
TreeNode *testRoot = NULL;
int score1 = 12;
int score2 = 6;
int score3 = 18;
int score4 = 3;
int score5 = 9;
int score6 = 15;
int score7 = 21;
testRoot = addToTree(testRoot, &score1, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score2, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score3, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score4, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score5, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score6, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score7, sizeof(int), compareIntEntries, NULL);
// Save all Adresses
TreeNode *node1 = testRoot;
TreeNode *node2 = testRoot->left;
TreeNode *node3 = testRoot->left->left;
TreeNode *node4 = testRoot->left->right;
TreeNode *node5 = testRoot->right;
TreeNode *node6 = testRoot->right->left;
TreeNode *node7 = testRoot->right->right;
clearTree(testRoot);
// Check if everything has been set to NULL
TEST_ASSERT_NULL(node1->data);
TEST_ASSERT_NULL(node1->data);
TEST_ASSERT_NULL(node2->data);
TEST_ASSERT_NULL(node3->data);
TEST_ASSERT_NULL(node4->data);
TEST_ASSERT_NULL(node5->data);
TEST_ASSERT_NULL(node6->data);
TEST_ASSERT_NULL(node7->data);
}
// tests if treeSize returns correct amount of nodes in Tree
// by using addToTree a given number of times and testing to see if
// the treeSize matches the number of nodes added
void test_treeSizeWorkingLikeExpected(void)
{
TreeNode *testRoot = NULL;
int nodeCount = 7;
unsigned int testTreeSize = 0;
int score1 = 12;
int score2 = 6;
int score3 = 18;
int score4 = 3;
int score5 = 9;
int score6 = 15;
int score7 = 21;
// Fill Tree
testRoot = addToTree(testRoot, &score1, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score2, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score3, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score4, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score5, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score6, sizeof(int), compareIntEntries, NULL);
testRoot = addToTree(testRoot, &score7, sizeof(int), compareIntEntries, NULL);
testTreeSize = treeSize(testRoot);
TEST_ASSERT_EQUAL(nodeCount, testTreeSize);
clearTree(testRoot);
}
// main, strings together all tests
int main()
{
UNITY_BEGIN();
printf("\n============================\nBinary Tree tests\n============================\n");
RUN_TEST(test_addToTreeExpandsTreeCorrectly);
RUN_TEST(test_nextTreeDataReturnsNextDataCorrectly);
RUN_TEST(test_clearTreeworksLikeExpected);
RUN_TEST(test_treeSizeWorkingLikeExpected);
return UNITY_END();
}

BIN
doble_initial.exe Normal file

Binary file not shown.

View File

@ -1,2 +1 @@
player_name;9943
player1;3999

View File

@ -35,14 +35,25 @@ $(program_obj_filesobj_files): %.o: %.c
# --------------------------
# Unit Tests
# --------------------------
unitTests:
echo "needs to be implemented"
# unitTests:
# echo "needs to be implemented"
bintree: bintree.c
$(CC) $(FLAGS) -c bintree bintree.c
bintreeTests: stack.o bintree.o bintreeTests.c $(unityfolder)/unity.c
$(CC) $(FLAGS) -o runbintreeTests bintreeTests.c bintree.o stack.o $(unityfolder)/unity.c
stack: stack.c
$(CC) $(FLAGS) -c stack stack.c
test_stack: stack.o test_stack.c $(unityfolder)/unity.c
$(CC) $(FLAGS) -o runstackTests test_stack.c stack.o $(unityfolder)/unity.c
test_numbers: numbers.o bintree.o stack.o test_numbers.c $(unityfolder)/unity.c
$(CC) $(FLAGS) -o run_numbersTests test_numbers.c numbers.o bintree.o stack.o $(unityfolder)/unity.c
# --------------------------
# Clean
# --------------------------

View File

@ -14,13 +14,106 @@
// 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.
static int compareUInt(const void *a, const void *b)
{
unsigned int A = *(unsigned int*)a;
unsigned int B = *(unsigned int*)b;
if (A < B) return -1;
if (A > B) return 1;
return 0;
}
// Sortiervergleich für qsort
int compareQsort(const void *a, const void *b)
{
unsigned int A = *(const unsigned int*)a;
unsigned int B = *(const unsigned int*)b;
if (A < B) return -1;
if (A > B) return +1;
return 0;
}
unsigned int *createNumbers(unsigned int len)
{
if (len < 2) return NULL;
srand((unsigned int)time(NULL));
// Speicher für das Array
unsigned int *numbers = malloc(sizeof(unsigned int) * len);
if (!numbers) return NULL;
TreeNode *root = NULL; // Baumwurzel
unsigned int value;
int isDuplicate;
//Array mit eindeutigen Zufallszahlen füllen
for (unsigned int i = 0; i < len; i++)
{
while (1)
{
value = (rand() % (2 * len)) + 1; // Zufallszahl 1..2*len
isDuplicate = 0;
TreeNode *newRoot = addToTree(
root,
&value,
sizeof(unsigned int),
compareUInt,
&isDuplicate
);
if (!isDuplicate)
{
// Neue Zahl - akzeptieren
root = newRoot;
numbers[i] = value;
break;
}
// Sonst neue Zahl generieren
}
}
//genau eine Zufallszahl duplizieren
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.
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
if (!numbers || len < 2) return 0;
unsigned int *copy = malloc(len * sizeof(unsigned int));
if (!copy) return 0;
// Array kopieren
memcpy(copy, numbers, len * sizeof(unsigned int));
// Sortieren
qsort(copy, len, sizeof(unsigned int), compareQsort);
// Doppelte Zahl finden
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;
}

BIN
numbers.o Normal file

Binary file not shown.

BIN
run_numbersTests.exe Normal file

Binary file not shown.

BIN
runbintreeTests.exe Normal file

Binary file not shown.

BIN
runstackTests.exe Normal file

Binary file not shown.

BIN
stack.o Normal file

Binary file not shown.

87
test_numbers.c Normal file
View File

@ -0,0 +1,87 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "numbers.h"
#include "unity/unity.h"
void setUp(void) {
// gehört zu unit-Grundaufbau
}
void tearDown(void) {
// gehört zu unit-Grundaufbau
}
// prüft, ob ein Array nur EIN Duplikat enthält
static int countDuplicates(const unsigned int *arr, unsigned int len) {
int count = 0;
for (unsigned int i = 0; i < len; i++) {
for (unsigned int j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
}
return count;
}
// Prüfen, ob createNumbers ein korrektes Array liefert
static void test_createNumbers_basic(void)
{
unsigned int len = 100;
unsigned int *arr = createNumbers(len);
TEST_ASSERT_NOT_NULL(arr); // prüft ob Speicher korrekt
// Prüfen: Länge stimmt
// Prüfen: Array enthält GENAU EIN Duplikat
int dupCount = countDuplicates(arr, len);
TEST_ASSERT_EQUAL_INT(1, dupCount);
free(arr);
}
// TEST 2: Prüfen, ob getDuplicate die richtige doppelte Zahl erkennt
static void test_getDuplicate_correctValue(void)
{
unsigned int len = 200;
unsigned int *arr = createNumbers(len);
TEST_ASSERT_NOT_NULL(arr);
unsigned int duplicate = getDuplicate(arr, len);
// Manuelle Kontrolle: Der gefundene Wert muss tatsächlich doppelt vorkommen
int occurrences = 0;
for (unsigned int i = 0; i < len; i++) {
if (arr[i] == duplicate) {
occurrences++;
}
}
TEST_ASSERT_EQUAL_INT(2, occurrences);
free(arr);
}
// TEST 3: getDuplicate gibt 0 aus bei Fehlern
static void test_getDuplicate_errors(void)
{
TEST_ASSERT_EQUAL_UINT(0, getDuplicate(NULL, 10));
TEST_ASSERT_EQUAL_UINT(0, getDuplicate((unsigned int*)1, 1)); // len < 2
}
// Testbereich
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_createNumbers_basic);
RUN_TEST(test_getDuplicate_correctValue);
RUN_TEST(test_getDuplicate_errors);
return UNITY_END();
}