immer gleiche ausgabe gefixt

This commit is contained in:
Simon Ehrnsperger 2025-12-15 11:08:02 +01:00
parent 9a37803c35
commit 80c2bfd3e0
2 changed files with 31 additions and 84 deletions

View File

@ -1,7 +0,0 @@
<<<<<<< HEAD
Alex;14964
=======
player_name;7977
player_name;7952
>>>>>>> 510edf85859637799b1b334b2bf6c5deff0adb80
player1;3999

108
numbers.c
View File

@ -7,7 +7,7 @@
// --- Vergleichsfunktionen --- // --- Vergleichsfunktionen ---
// 1. Vergleichsfunktion für qsort (vergleicht unsigned int-Werte) // 1. Vergleichsfunktion für qsort
int compare_unsigned_int(const void *a, const void *b) { int compare_unsigned_int(const void *a, const void *b) {
unsigned int arg1 = *(const unsigned int*)a; unsigned int arg1 = *(const unsigned int*)a;
unsigned int arg2 = *(const unsigned int*)b; unsigned int arg2 = *(const unsigned int*)b;
@ -17,10 +17,8 @@ int compare_unsigned_int(const void *a, const void *b) {
return 0; return 0;
} }
// 2. Vergleichsfunktion für den Binärbaum (vergleicht die *Daten* der Knoten) // 2. Vergleichsfunktion für den Binärbaum
// Die Argumente sind Pointer auf die *Daten* (void*), d.h. Pointer auf unsigned int.
int compare_tree_data(const void *arg1, const void *arg2) { int compare_tree_data(const void *arg1, const void *arg2) {
// Cast der void*-Pointer auf unsigned int*-Pointer
unsigned int val1 = *(const unsigned int*)arg1; unsigned int val1 = *(const unsigned int*)arg1;
unsigned int val2 = *(const unsigned int*)arg2; unsigned int val2 = *(const unsigned int*)arg2;
@ -29,100 +27,66 @@ int compare_tree_data(const void *arg1, const void *arg2) {
return 0; return 0;
} }
//TODO: getDuplicate und createNumbers implementieren /* * Erzeugt ein Array mit (len - 1) eindeutigen Zufallszahlen und einem Duplikat. */
/* * * 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 - 1) eindeutigen Zufallszahlen und einem Duplikat.
* Die Duplikatprüfung erfolgt über den Binärbaum (addToTree).
*/
unsigned int *createNumbers(unsigned int len) { unsigned int *createNumbers(unsigned int len) {
if (len == 0) { if (len == 0) return NULL;
return NULL;
} // --- NEU: Zufallsgenerator initialisieren ---
// Wir verwenden eine statische Variable, damit srand nur ein einziges Mal
// aufgerufen wird, auch wenn createNumbers mehrfach benutzt wird.
static int is_seeded = 0;
if (!is_seeded) {
srand(time(NULL)); // Initialisiert den Generator mit der aktuellen Zeit
is_seeded = 1;
}
// ---------------------------------------------
// 1. Initialisierung
// Der BST wird zunächst als NULL initialisiert, da addToTree rekursiv arbeitet.
TreeNode *root = NULL; TreeNode *root = NULL;
// 2. Speicher für das Ziel-Array allokieren
unsigned int *numbers = (unsigned int *)malloc(len * sizeof(unsigned int)); unsigned int *numbers = (unsigned int *)malloc(len * sizeof(unsigned int));
if (numbers == NULL) { if (numbers == NULL) return NULL;
return NULL;
}
unsigned int count = 0; unsigned int count = 0;
unsigned int max_val = 2 * len; unsigned int max_val = 2 * len;
// Speichert den Wert, der später dupliziert wird (aus dem Array gewählt)
unsigned int value_to_duplicate = 0; unsigned int value_to_duplicate = 0;
// 3. Erzeugen von len - 1 eindeutigen Zufallszahlen // Erzeugen von len - 1 eindeutigen Zufallszahlen
while (count < len - 1) { while (count < len - 1) {
unsigned int random_num = (rand() % max_val) + 1; unsigned int random_num = (rand() % max_val) + 1;
int is_duplicate = 0; int is_duplicate = 0;
// Wir müssen die Zahl als dynamisch allokierten Speicher übergeben, // Wir übergeben die Adresse der lokalen Variable. addToTree kopiert den Wert.
// da addToTree eine Kopie davon erwartet. root = addToTree(root, &random_num, sizeof(unsigned int), compare_tree_data, &is_duplicate);
unsigned int *num_ptr = (unsigned int *)malloc(sizeof(unsigned int));
if (num_ptr == NULL) {
// cleanup: Baum und bereits allokiertes Array freigeben
clearTree(root);
free(numbers);
return NULL;
}
*num_ptr = random_num;
// Fügen in den Baum ein:
// root MUSS das Ergebnis der rekursiven addToTree-Funktion speichern!
root = addToTree(root, num_ptr, sizeof(unsigned int), compare_tree_data, &is_duplicate);
if (root == NULL) { if (root == NULL) {
// Schwerwiegender Fehler bei der Speicherallokation innerhalb von addToTree
clearTree(root);
free(numbers); free(numbers);
free(num_ptr); // Datenpointer freigeben, falls Fehler vor der Kopie auftrat
return NULL; return NULL;
} }
if (is_duplicate == 0) { if (is_duplicate == 0) {
// Erfolg: Zahl war neu und wurde eingefügt (die Datenkopie liegt nun im Baum) // Erfolg: Zahl war neu
numbers[count] = random_num; numbers[count] = random_num;
count++; count++;
// value_to_duplicate merken // Merken für späteres Duplizieren
value_to_duplicate = random_num; value_to_duplicate = random_num;
// Den lokalen num_ptr NICHT freigeben, da seine Kopie im Baum verwaltet wird.
} else {
// Fehler: Duplikat, wurde NICHT eingefügt.
// Den lokal allokierten Pointer MÜSSEN wir freigeben, da er nicht in den Baum ging.
free(num_ptr);
} }
// Bei Duplikat (is_duplicate == 1) einfach weitermachen -> while läuft weiter
} }
// 4. Duplizieren eines Eintrags // Duplizieren eines Eintrags an die letzte Stelle
// Der duplizierte Wert wird an die letzte Stelle gesetzt.
if (len > 1) { if (len > 1) {
// Wir verwenden value_to_duplicate, um sicherzustellen, dass die Zahl aus dem Array stammt. // Fallback, falls value_to_duplicate noch 0 ist (sollte logisch nicht passieren bei len > 1)
// Wenn len sehr groß ist, wird einfach eine zufällige Zahl aus dem gefüllten Bereich gewählt.
if (value_to_duplicate == 0) { if (value_to_duplicate == 0) {
value_to_duplicate = numbers[rand() % (len - 1)]; value_to_duplicate = numbers[rand() % (len - 1)];
} }
numbers[len - 1] = value_to_duplicate; numbers[len - 1] = value_to_duplicate;
} }
// Speicher des Baumes freigeben
// 5. Speicher des Baumes freigeben
// clearTree gibt alle Knoten und die darin enthaltenen Datenkopien frei.
clearTree(root); clearTree(root);
// 6. Mischen (Shuffling) des Arrays, um die Ordnung zu randomisieren // Mischen (Fisher-Yates Shuffle)
for (unsigned int i = len - 1; i > 0; i--) { for (unsigned int i = len - 1; i > 0; i--) {
unsigned int j = rand() % (i + 1); unsigned int j = rand() % (i + 1);
unsigned int temp = numbers[i]; unsigned int temp = numbers[i];
@ -132,26 +96,18 @@ unsigned int *createNumbers(unsigned int len) {
return numbers; return numbers;
} }
// Returns only the only number in numbers which is present twice. Returns zero on errors.
/* * Sortiert das Array und erkennt das Duplikat durch Vergleich benachbarter Elemente.
* (O(N log N) wegen qsort)
*/
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) {
if (len < 2) {
return 0; // Fehler
}
// 1. Array duplizieren, da das Original const ist und sortiert werden muss /* * Sortiert das Array und erkennt das Duplikat. */
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) {
if (len < 2) return 0;
unsigned int *sorted_numbers = (unsigned int *)malloc(len * sizeof(unsigned int)); unsigned int *sorted_numbers = (unsigned int *)malloc(len * sizeof(unsigned int));
if (sorted_numbers == NULL) { if (sorted_numbers == NULL) return 0;
return 0;
}
memcpy(sorted_numbers, numbers, len * sizeof(unsigned int)); memcpy(sorted_numbers, numbers, len * sizeof(unsigned int));
// 2. Sortieren des Arrays
qsort(sorted_numbers, len, sizeof(unsigned int), compare_unsigned_int); qsort(sorted_numbers, len, sizeof(unsigned int), compare_unsigned_int);
// 3. Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente
unsigned int duplicate = 0; unsigned int duplicate = 0;
for (unsigned int i = 0; i < len - 1; i++) { for (unsigned int i = 0; i < len - 1; i++) {
if (sorted_numbers[i] == sorted_numbers[i+1]) { if (sorted_numbers[i] == sorted_numbers[i+1]) {
@ -161,7 +117,5 @@ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) {
} }
free(sorted_numbers); free(sorted_numbers);
// 4. Ergebnis zurückgeben
return duplicate; return duplicate;
} }