Compare commits

..
1 Commits
Author SHA1 Message Date
rupprechtmo100591 510edf8585 Änderung von bintree.c 2025-12-13 09:51:34 +01:00
7 changed files with 93 additions and 137 deletions

No files matched your search

+76
View File
@@ -12,7 +12,43 @@
// 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)
{
// 1. Leerer Baum -> neuen Knoten anlegen
if (root == NULL)
{
TreeNode *node = malloc(sizeof(TreeNode)); //Speicherreservierung
if (!node) return NULL; //Abbruch, wenn kein Speicher verfügbar
node->data = malloc(dataSize); //Speicher für Daten reservieren
if(!node->data) //Bei Fehler -> freigeben des Knotens und abbrechen
{
free(node);
return NULL;
}
memcpy(node->data, data, dataSize); //Daten kopieren (nicht Zeiger)
node->left = node->right = NULL; //Neuer Knoten hat keine Kinder
if (isDuplicate) *isDuplicate = 0; //Rückmeldung (kein Duplikat)
return node;
}
//2. Vergleich, um Einfügerichtung zu bestimmen
int cmp = compareFct(data, root->data);
if (cmp < 0) //kleiner nach links weitergeben (rekursiv)
{
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
}
else if (cmp > 0) //größer nach rechts weitergeben
{
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
}
else //Duplikat -> wird nicht eingefügt (keine Änderung am Baum)
{
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.
@@ -20,17 +56,57 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
// push the top node and push all its left nodes.
void *nextTreeData(TreeNode *root)
{
static StackNode *iterStack = NULL; //behält den Wert zwischen Funktionsaufrufen
if (root != NULL) //Wird ein neuer Baum übergeben?
{
clearStack(iterStack); // alten Stack löschen
iterStack = NULL;
TreeNode *cur = root; //Root + alle linken Knoten auf Stack pushen
while (cur != NULL)
{
iterStack = push(iterStack, cur);
cur = cur->left;
}
}
if (iterStack == NULL) //Kein Baum mehr -> besuchen aller Knoten beendet
return NULL;
//Top-Knoten (als nächtes Reihe)
TreeNode *node = (TreeNode *)top(iterStack); //Top-Knoten als nächste Reihe
iterStack = pop(iterStack); //entfernen des Kontens
//Rechtsknoten
TreeNode *right = node->right; //nach Besuch bei rechten Knoten in rechten Teilbaum
while (right != NULL)
{
iterStack = push(iterStack, right);
right = right->left; //von dort ganz nach links und alles pushen
}
return node->data;
}
// Releases all memory resources (including data copies).
void clearTree(TreeNode *root)
{
if (root == NULL) //Abbruchbedienung
return;
clearTree(root->left); //links und rechts löschen
clearTree(root->right);
free(root->data); //Daten freigeben
free(root);
}
// Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root)
{
if (root == NULL) //leerer Baum
return 0;
return 1 + treeSize(root->left) + treeSize(root->right); //Größe = 1 + Größe links + Größe rechts
}
BIN
View File
Binary file not shown.
+2 -1
View File
@@ -1,2 +1,3 @@
Alex;14964
player_name;7977
player_name;7952
player1;3999
+11 -25
View File
@@ -1,5 +1,5 @@
CC = gcc
CFLAGS = -g -Wall -lm
FLAGS = -g -Wall -lm
ifeq ($(OS),Windows_NT)
include makefile_windows.variables
@@ -24,40 +24,26 @@ doble_initial:
# --------------------------
# Selbst implementiertes Programm bauen
# --------------------------
program_obj_files = main.o stack.o bintree.o numbers.o timer.o highscore.o
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
doble : $(program_obj_files)
$(CC) $(CFLAGS) $^ -o doble
doble : main.o $(program_obj_files)
$(CC) $(FLAGS) $^ -o doble
$(program_obj_filesobj_files): %.o: %.c
$(CC) -c $(FLAGS) $^ -o $@
# --------------------------
# Unit Tests
# --------------------------
TEST_STACK_EXEC = runtest_stack.exe
unitTests: $(TEST_STACK_EXEC)
@echo "--- Starte Stack Unit Tests ---"
@echo "Versuche auszuführen: $(TEST_STACK_EXEC)"
$(TEST_STACK_EXEC)
@echo "--- Stack Unit Tests abgeschlossen ---"
$(TEST_STACK_EXEC): test_stack.o stack.o
$(CC) $(CFLAGS) -I$(unityfolder) test_stack.o stack.o $(unityfolder)/unity.c -o $@ $(BINARIES)/libdoble_complete.a
test_stack.o: test_stack.c
$(CC) -c $(CFLAGS) -I$(unityfolder) $< -o $@
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
unitTests:
echo "needs to be implemented"
# --------------------------
# Clean
# --------------------------
clean:
ifeq ($(OS),Windows_NT)
del /f *.o *.exe doble $(TEST_STACK_EXEC)
del /f *.o doble
else
rm -f *.o *.exe doble $(TEST_STACK_EXEC)
endif
.PHONY: doble_initial doble unitTests $(TEST_STACK_EXEC) clean
rm -f *.o doble
endif
+3 -38
View File
@@ -10,59 +10,24 @@
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data)
{
StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));
if(!newNode) {
return NULL;
}
newNode->data = data;
newNode->next = stack;
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.)
// 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)
{
if(!stack) {
return NULL;
}
StackNode *topNode = stack;
stack = stack->next;
free(topNode);
return stack;
}
// Returns the data of the top element.
void *top(StackNode *stack)
{
if(!stack){
return NULL;
}
return stack->data;
}
// Clears stack and releases all memory.
StackNode *clearStack(StackNode *stack)
void clearStack(StackNode *stack)
{
StackNode *current = stack;
StackNode *next_node;
while(current){
next_node = current->next;
free(current);
current = next_node;
}
return NULL;
}
+1 -6
View File
@@ -8,10 +8,6 @@ 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;
}StackNode;
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data);
@@ -24,7 +20,6 @@ StackNode *pop(StackNode *stack);
void *top(StackNode *stack);
// Clears stack and releases all memory.
StackNode *clearStack(StackNode *stack);
void clearStack(StackNode *stack);
#endif
-67
View File
@@ -1,67 +0,0 @@
#include <stdlib.h>
#include "unity/unity.h"
#include "stack.h"
void setUp(void) {}
void tearDown(void) {}
static StackNode *stack = NULL; // Für gemeinsame Benutzung in Tests
void test_push_and_top_should_return_last_integer(void) {
int *v1 = malloc(sizeof(int));
int *v2 = malloc(sizeof(int));
int *v3 = malloc(sizeof(int));
*v1 = 12; *v2 = 34; *v3 = 56;
// Push Werte auf Stack
stack = push(stack, v1);
TEST_ASSERT_NOT_NULL(stack);
TEST_ASSERT_EQUAL_INT(12, *(int *)top(stack));
stack = push(stack, v2);
TEST_ASSERT_EQUAL_INT(34, *(int *)top(stack));
stack = push(stack, v3);
TEST_ASSERT_EQUAL_INT(56, *(int *)top(stack));
// Ressourcen werden in anderem Test wieder entfernt!
}
void test_pop_should_remove_and_free_integers(void) {
// Gibt die gleichen Werte wie im vorherigen Push-Test frei
int *val;
val = top(stack);
TEST_ASSERT_EQUAL_INT(56, *val);
free(val);
stack = pop(stack);
val = top(stack);
TEST_ASSERT_EQUAL_INT(34, *val);
free(val);
stack = pop(stack);
val = top(stack);
TEST_ASSERT_EQUAL_INT(12, *val);
free(val);
stack = pop(stack);
TEST_ASSERT_NULL(stack);
}
void test_stack_empty_behavior(void) {
// Nach allen pops/clear-Operationen sollte Stack NULL sein
TEST_ASSERT_NULL(top(stack));
StackNode *tmp = pop(stack);
TEST_ASSERT_NULL(tmp);
stack = clearStack(stack); // Sollte NULL bleiben
TEST_ASSERT_NULL(stack);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_push_and_top_should_return_last_integer);
RUN_TEST(test_pop_should_remove_and_free_integers);
RUN_TEST(test_stack_empty_behavior);
return UNITY_END();
}