generated from freudenreichan/info2Praktikum-DobleSpiel
comments
This commit is contained in:
parent
cd4f74f9a5
commit
bb8bd2ace8
32
numbers.c
32
numbers.c
@ -41,10 +41,10 @@ unsigned int *createNumbers(unsigned int len)
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
// Sicherheitscheck für len (Minimum 3, siehe main.c)
|
||||
// Sicherheitscheck für len (Minimum 3, da sonst kein Duplikat möglich ist)
|
||||
if (len < 3) return NULL;
|
||||
|
||||
// Allokiere Speicher für 'len' unsigned int
|
||||
// Array auf dem Heap allokieren
|
||||
unsigned int *numbers = (unsigned int *)malloc(len * sizeof(unsigned int));
|
||||
|
||||
if (numbers == NULL)
|
||||
@ -53,23 +53,23 @@ unsigned int *createNumbers(unsigned int len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 2. Binären Suchbaum initialisieren
|
||||
// Binären Suchbaum initialisieren für Duplikatprüfung
|
||||
TreeNode *treeRoot = NULL;
|
||||
|
||||
// Variablen für Schleife und Zufallszahl
|
||||
unsigned int randomNumber;
|
||||
int isDuplicate; // Flag für addToTree
|
||||
int isDuplicate; // Flag von addToTree gesetzt
|
||||
|
||||
// Die Schleife läuft nur bis len - 1, da die letzte Zahl das Duplikat wird
|
||||
for (unsigned int i = 0; i < len - 1; i++)
|
||||
{
|
||||
do
|
||||
{
|
||||
// 3a. Zufallszahl generieren [1, 2 * len]
|
||||
// Zufallszahl generieren [1, 2 * len]
|
||||
// Formel: (rand() % (Obergrenze - Untergrenze + 1)) + Untergrenze
|
||||
randomNumber = (rand() % (2 * len)) + 1;
|
||||
|
||||
// 3b. Zahl in den Binärbaum einfügen (und Duplikat prüfen)
|
||||
// Zahl in den Binärbaum einfügen (und Duplikat prüfen)
|
||||
// addToTree gibt treeRoot zurück, das wird für die nächste Iteration gespeichert.
|
||||
// isDuplicate wird auf 1 gesetzt, wenn die Zahl schon existiert.
|
||||
treeRoot = addToTree(
|
||||
@ -89,11 +89,11 @@ unsigned int *createNumbers(unsigned int len)
|
||||
|
||||
} while (isDuplicate); // Solange eine Duplikat-Nummer generiert wurde, wiederhole.
|
||||
|
||||
// 4. Eindeutige Zahl im Array speichern
|
||||
// Eindeutige Zahl im Array speichern
|
||||
numbers[i] = randomNumber;
|
||||
}
|
||||
|
||||
// 5. Duplikat erzeugen (letzter Eintrag des Arrays)
|
||||
// Duplikat erzeugen (letzter Eintrag des Arrays)
|
||||
|
||||
// Wähle einen zufälligen Index der bereits gefüllten eindeutigen Zahlen [0, len - 2]
|
||||
// Wir wählen aus den len-1 bereits gefüllten Einträgen.
|
||||
@ -102,7 +102,7 @@ unsigned int *createNumbers(unsigned int len)
|
||||
// Kopiere den Wert des zufälligen Index auf das letzte Element
|
||||
numbers[len - 1] = numbers[duplicateIndex];
|
||||
|
||||
// 6. Aufräumen: Speicher des Binärbaums freigeben (sehr wichtig!)
|
||||
// Speicher des Binärbaums freigeben (sehr wichtig!)
|
||||
// Voraussetzung: clearTree ist in bintree.c implementiert.
|
||||
clearTree(treeRoot);
|
||||
|
||||
@ -114,10 +114,13 @@ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
||||
{
|
||||
unsigned int duplicate = 0; // Rückgabewert (0 bei Fehler)
|
||||
|
||||
// 1. Array-Kopie auf dem Heap erstellen (muss mit free freigegeben werden!)
|
||||
if (len < 3) return 0; // Spielanforderung
|
||||
|
||||
// Array-Kopie auf dem Heap erstellen, da qsort in-place sortiert.
|
||||
unsigned int sizeInBytes = len * sizeof(unsigned int);
|
||||
unsigned int *tempArray = (unsigned int *)malloc(sizeInBytes);
|
||||
|
||||
|
||||
if (tempArray == NULL) {
|
||||
return 0; // Speicherfehler
|
||||
}
|
||||
@ -125,14 +128,15 @@ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
||||
// Daten kopieren
|
||||
memcpy(tempArray, numbers, sizeInBytes);
|
||||
|
||||
// 2. Sortieren der Kopie mit qsort (siehe Skript 14_effiziente_sortieralgorithmen.pdf)
|
||||
// qsort hat eine durchschnittliche Komplexität von O(n log n) [cite: 261]
|
||||
// Sortieren der Kopie mit qsort (siehe Skript effiziente sortieralgorithmen)
|
||||
// qsort hat eine durchschnittliche Komplexität von O(n log n)
|
||||
qsort(tempArray, len, sizeof(unsigned int), compareNumbers);
|
||||
|
||||
// 3. Duplikat finden durch Vergleich benachbarter Elemente
|
||||
// Duplikat finden durch Vergleich benachbarter Elemente
|
||||
for (unsigned int i = 0; i < len - 1; i++)
|
||||
{
|
||||
// Vergleiche Element i mit Element i+1
|
||||
// Da das Array sortiert ist, stehen Duplikate nebeneinander
|
||||
if (tempArray[i] == tempArray[i + 1])
|
||||
{
|
||||
duplicate = tempArray[i];
|
||||
@ -140,7 +144,7 @@ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Speicher freigeben!
|
||||
// Speicher freigeben!
|
||||
free(tempArray);
|
||||
|
||||
return duplicate;
|
||||
|
||||
36
stack.c
36
stack.c
@ -10,15 +10,15 @@
|
||||
// Pushes data as pointer onto the stack.
|
||||
StackNode *push(StackNode *stack, void *data)
|
||||
{
|
||||
//Speicher reservieren
|
||||
// Speicher reservieren für neuen Knoten (muss auf dem Heap liegen!)
|
||||
StackNode *newNode = malloc(sizeof(StackNode));
|
||||
if (!newNode)
|
||||
return stack;
|
||||
return stack; // Fehlerfall: Speicher konnte nicht allokiert werden
|
||||
|
||||
newNode->data = data;
|
||||
newNode->next = stack;
|
||||
newNode->data = data; // Datenpointer übernehmen
|
||||
newNode->next = stack; // Der bisherige Stack ist jetzt der Nächste (LIFO)
|
||||
|
||||
return newNode;
|
||||
return newNode; // Der neue Knoten ist jetzt die Spitze des Stacks
|
||||
|
||||
}
|
||||
|
||||
@ -26,38 +26,36 @@ StackNode *push(StackNode *stack, void *data)
|
||||
// freed by caller.)
|
||||
StackNode *pop(StackNode *stack)
|
||||
{
|
||||
// überprüfen ob stack einen wert besitzt
|
||||
// Check, ob der Stack leer ist
|
||||
if (!stack)
|
||||
return NULL;
|
||||
//oberstes element raussuchen und dieses auf free setzen
|
||||
//den pointer dazu auf NULL setzen
|
||||
|
||||
StackNode *next = stack->next;
|
||||
free(stack);
|
||||
return next;
|
||||
//stack returnen
|
||||
StackNode *next = stack->next; // Speichere den Pointer auf das nächste Element
|
||||
free(stack); // Gib den Speicher des obersten Knotens frei
|
||||
|
||||
return next; // Gebe das neue oberste Element zurück
|
||||
}
|
||||
|
||||
// Returns the data of the top element.
|
||||
void *top(StackNode *stack)
|
||||
{
|
||||
//funktions return ist oberstes stack element
|
||||
// Check, ob der Stack leer ist
|
||||
if (!stack)
|
||||
return NULL;
|
||||
|
||||
StackNode *next = stack->data;
|
||||
return next;
|
||||
// Gebe nur die Daten zurück, ohne den Stack zu verändern
|
||||
return stack->data;
|
||||
}
|
||||
|
||||
// Clears stack and releases all memory.
|
||||
void clearStack(StackNode *stack)
|
||||
{
|
||||
|
||||
// Iteriere solange, bis der Stack leer ist
|
||||
while(stack != NULL)
|
||||
{
|
||||
StackNode *next = stack->next;
|
||||
free(stack);
|
||||
stack = next;
|
||||
StackNode *next = stack->next; // Speichere den Nachfolger
|
||||
free(stack); // Gib den aktuellen Knoten frei
|
||||
stack = next; // Gehe zum nächsten Knoten
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user