Files

4.2 KiB
Raw Permalink Blame History

Praktikum Informatik 2 – Projekt „Doble“

Dieses Repository enthält unsere Umsetzung des Praktikumsprojekts Doble (Algorithmen und Datenstrukturen in C). Ziel des Projekts ist die Implementierung eines generischen Stacks, eines binären Suchbaums sowie einer Zufallszahlengenerierung mit Duplikaterkennung mittels qsort – inklusive vollständiger Unit-Tests und sauberer Speicherverwaltung.


Arbeitsteilung

Jede Person implementiert ihre zugewiesenen Module sowie die dazugehörigen Unit-Tests eigenständig.

Bereich Flo Jamin
Module & Logik stack.h, stack.c, numbers.c (+ Memory-Leak-Fix in main.c) bintree.c
Unit-Tests test_stack.c, test_numbers.c test_bintree.c

Aufgabenpakete im Detail

Flo: Stack, Zahlenlogik & zugehörige Tests

  • Stack (stack.h, stack.c)
    • Definition von struct StackNode (void *data, struct StackNode *next) in stack.h.
    • Implementierung von push, pop, top und clearStack (pop gibt nur den Knoten selbst frei, nicht den data-Pointer).
  • Zahlen & Sortierung (numbers.c & main.c)
    • createNumbers: Array der Größe len allokieren, len - 1 eindeutige Zufallszahlen (1 bis 2 * len) mithilfe des Binärbaums (addToTree) generieren, einen zufälligen Eintrag duplizieren und den Baum anschließend mit clearTree freigeben.
    • getDuplicate: Arbeitskopie des const-Arrays anlegen, mit qsort sortieren (Überlauf-sichere Vergleichsfunktion (va > vb) - (va < vb)), benachbarte Elemente vergleichen, Kopie freigeben und das Duplikat zurückgeben.
    • Ergänzen von free(numbers); am Programmende in main.c, um Speicherlecks zu vermeiden.
  • Unit-Tests (test_stack.c, test_numbers.c)
    • test_stack.c: top/pop auf leerem Stack (NULL), LIFO-Reihenfolge bei mehreren push/pop-Operationen, clearStack auf leerem und gefülltem Stack.
    • test_numbers.c: createNumbers auf Fehlerfälle (len == 0), Wertebereich (1 bis 2 * len) und exakt ein Duplikat prüfen; getDuplicate mit Test-Arrays (Duplikat vorne, mittig, hinten), NULL/len < 2 sowie Unveränderlichkeit des Eingabearrays testen.

Jamin: Generischer Binärbaum & zugehörige Tests

  • Binärer Suchbaum (bintree.c)
    • addToTree: Rekursives Einfügen; beim Erstellen eines neuen Knotens Speicher mit malloc(dataSize) reservieren, Inhalt via memcpy kopieren und compareFct sowie isDuplicate korrekt behandeln.
    • treeSize: Rekursives Zählen aller Knoten (0 bei root == NULL).
    • clearTree: Rekursives Freigeben in Post-Order (left, right, node->data, node).
    • nextTreeData: Iterative In-Order-Traversierung mit static StackNode *stack = NULL; (analog zu strtok). Bei root != NULL alten Stack leeren und root sowie alle linken Kindknoten pushen; bei root == NULL obersten Knoten poppen, dessen rechten Teilbaum inkl. aller linken Kinder pushen und data zurückgeben.
  • Unit-Tests (test_bintree.c)
    • addToTree: Einfügen in leeren Baum, Sortierreihenfolge, Verhalten mit isDuplicate == NULL vs. isDuplicate != NULL (Flag-Werte 0 und 1).
    • treeSize: Überprüfung für leeren (0) und gefüllten Baum.
    • nextTreeData: Sortierte In-Order-Ausgabe, NULL-Rückgabe am Ende sowie Reset bei Übergabe eines neuen Baums.
    • clearTree: Aufruf mit NULL und gefülltem Baum (inkl. Prüfung auf Speicherlecks).

Zeitplan & Workflow

  1. Initialisierung: Flo legt struct StackNode in stack.h fest und pusht die Datei, damit Jamin ohne Blockade mit bintree.c starten kann.
  2. Parallele Entwicklung:
    • Flo implementiert stack.c, test_stack.c, numbers.c und test_numbers.c.
    • Jamin implementiert bintree.c und test_bintree.c.
  3. Integration & Abnahme:
    • Zusammenführen aller Module auf main.
    • Kompilieren ohne Compiler-Warnungen und Ausführen aller Unit-Tests.
    • Speicherleck-Prüfung (z. B. mit Valgrind oder AddressSanitizer).

Kompilieren & Ausführen

# Vollständiges Spiel bauen und starten
make doble
./doble <player_name>

# Unit-Tests bauen und ausführen (je nach Makefile-Targets)
make test_stack && ./test_stack
make test_numbers && ./test_numbers
make test_bintree && ./test_bintree