#include "numbers.h" #include "bintree.h" #include #include #include // TODO: getDuplicate und createNumbers implementieren /**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. // vergleicht zwei Werte: ab: 1 a=b: 0 int compareUnsignedInt(const void *a, const void *b) { unsigned int x = *(unsigned int *)a; unsigned int y = *(unsigned int *)b; return (x < y) ? -1 : (x > y); } unsigned int *createNumbers(unsigned int len) { if (len < 2) // Duplikat bei zwei Einträgen sinnlos return NULL; unsigned int *numbersArray = malloc( sizeof(unsigned int) * len); // Speicher für das Ausgabearray reservieren: // Größe eines Eintrags * Größe des Arrays if (!numbersArray) // Speicher konnte nicht reserviert werden return NULL; TreeNode *root = NULL; // Binärbaum zum Generieren der Zufallszahlen ohne Duplikate for (unsigned int i = 0; i < len; i++) { unsigned int currentNumber; int isDuplicate; do { // mindestens eine Zufallszahl erzeugen currentNumber = (rand() % (2 * len)) + 1; // Zahlenbereich 1 bis 2*len isDuplicate = 0; root = addToTree(root, ¤tNumber, sizeof(unsigned int), compareUnsignedInt, &isDuplicate); // compareUnsignedInt wird zum Verwenden // bei Vergleichen übergeben } while (isDuplicate); // wenn isDuplicate gesetzt wird, muss eine neue Zahl // erzeugt werden, die Schleife wird wiederholt numbersArray[i] = currentNumber; } // Ein zufälliges Duplikat erzeugen unsigned int duplicateIndex = rand() % len; // Index des Duplikats per Zufall bestimmen unsigned int newIndex; do { newIndex = rand() % len; } while (newIndex == duplicateIndex); // zweiten Index bestimmen, der nicht // mit dem ersten übereinstimmt numbersArray[newIndex] = numbersArray[duplicateIndex]; // Wert vom ersten Index kopieren clearTree(&root); // Speicher wieder freigeben, wird nicht mehr benötigt return numbersArray; } // Returns only the only number in numbers which is present twice. Returns zero // on errors. unsigned int getDuplicate( const unsigned int *numbers, unsigned int len) { // array numbers, sowie die Länge wird übergeben if (!numbers || len < 2) return 0; // fehlerhaftes Array TreeNode *root = NULL; // leerer Baum unsigned int duplicateValue = 0; // Wert des Duplikats for (unsigned int i = 0; i < len && duplicateValue == 0; i++) { // Schleife int isDuplicate = 0; // Zahl in den Baum einfügen root = addToTree(root, &numbers[i], sizeof(unsigned int), compareUnsignedInt, &isDuplicate); // Duplikat erkannt if (isDuplicate && duplicateValue == 0) { duplicateValue = numbers[i]; // Duplikat merken, for-Schleife wird beendet } } clearTree(&root); // Baum freigeben return duplicateValue; // 0, falls kein Duplikat }