#include #include #include #include #include "numbers.h" #include "bintree.h" // --- Vergleichsfunktionen --- // 1. Vergleichsfunktion für qsort int compare_unsigned_int(const void *a, const void *b) { unsigned int arg1 = *(const unsigned int*)a; unsigned int arg2 = *(const unsigned int*)b; if (arg1 < arg2) return -1; if (arg1 > arg2) return 1; return 0; } // 2. Vergleichsfunktion für den Binärbaum int compare_tree_data(const void *arg1, const void *arg2) { unsigned int val1 = *(const unsigned int*)arg1; unsigned int val2 = *(const unsigned int*)arg2; if (val1 < val2) return -1; if (val1 > val2) return 1; return 0; } /* * Erzeugt ein Array mit (len - 1) eindeutigen Zufallszahlen und einem Duplikat. */ unsigned int *createNumbers(unsigned int len) { if (len == 0) 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; } // --------------------------------------------- TreeNode *root = NULL; unsigned int *numbers = (unsigned int *)malloc(len * sizeof(unsigned int)); if (numbers == NULL) return NULL; unsigned int count = 0; unsigned int max_val = 2 * len; unsigned int value_to_duplicate = 0; // Erzeugen von len - 1 eindeutigen Zufallszahlen while (count < len - 1) { unsigned int random_num = (rand() % max_val) + 1; int is_duplicate = 0; // Wir übergeben die Adresse der lokalen Variable. addToTree kopiert den Wert. root = addToTree(root, &random_num, sizeof(unsigned int), compare_tree_data, &is_duplicate); if (root == NULL) { free(numbers); return NULL; } if (is_duplicate == 0) { // Erfolg: Zahl war neu numbers[count] = random_num; count++; // Merken für späteres Duplizieren value_to_duplicate = random_num; } // Bei Duplikat (is_duplicate == 1) einfach weitermachen -> while läuft weiter } // Duplizieren eines Eintrags an die letzte Stelle if (len > 1) { // Fallback, falls value_to_duplicate noch 0 ist (sollte logisch nicht passieren bei len > 1) if (value_to_duplicate == 0) { value_to_duplicate = numbers[rand() % (len - 1)]; } numbers[len - 1] = value_to_duplicate; } // Speicher des Baumes freigeben clearTree(root); // Mischen (Fisher-Yates Shuffle) for (unsigned int i = len - 1; i > 0; i--) { unsigned int j = rand() % (i + 1); unsigned int temp = numbers[i]; numbers[i] = numbers[j]; numbers[j] = temp; } return numbers; } /* * 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)); if (sorted_numbers == NULL) return 0; memcpy(sorted_numbers, numbers, len * sizeof(unsigned int)); qsort(sorted_numbers, len, sizeof(unsigned int), compare_unsigned_int); unsigned int duplicate = 0; for (unsigned int i = 0; i < len - 1; i++) { if (sorted_numbers[i] == sorted_numbers[i+1]) { duplicate = sorted_numbers[i]; break; } } free(sorted_numbers); return duplicate; }