From 16fa87e08131694e3095e3bcd6bacead70396103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannik=20Baumg=C3=A4rtner?= Date: Thu, 11 Dec 2025 08:55:14 +0100 Subject: [PATCH] =?UTF-8?q?Restliche=20Kommentare=20eingef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bintree.o | Bin 5736 -> 0 bytes highscore.o | Bin 8645 -> 0 bytes main.o | Bin 5965 -> 0 bytes numbers.c | 166 +++++++++++++++++++++++++++++++++++++------------ numbers.o | Bin 6253 -> 0 bytes stack.o | Bin 3927 -> 0 bytes test_numbers.c | 88 ++++++++++++++++++++------ timer.o | Bin 3080 -> 0 bytes 8 files changed, 196 insertions(+), 58 deletions(-) delete mode 100644 bintree.o delete mode 100644 highscore.o delete mode 100644 main.o delete mode 100644 numbers.o delete mode 100644 stack.o delete mode 100644 timer.o diff --git a/bintree.o b/bintree.o deleted file mode 100644 index 1e0c0fc34907167234365d92d748cbaa9ddcd288..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5736 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 diff --git a/main.o b/main.o deleted file mode 100644 index a04c31b9e0d3615a8831c155da59398b3ff9c4d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5965 zcmbtYU2GiH6}~gGcX!t7f5-6;kc^4#I1ukTiQ@z(0Vnptx+TFPu|lZnGTxoton&`* zJ2PvWh%~7TNGlU5u2Pi;)aIq)rHDT80184BC;^E|R*Om=PzmBMh*qLiRg4;uo^$Wa z?5rKB553afd+v9>d(OE(b7tA_VM>MHgy$y+HYZuH_AlMN8{> ztH^8N+%Pm_WN0ilTs!tl@OgWXkVhR}J>xYWitQMwAzp;|q(}_}_JFsGucWKN-Y>z( zpB#Izl$(YIwKmFux;vYgFGs?|MTG#QpBAo$wS;KHh885o1Jf(4cc?2R3oPEm==7%29d=xifE6(^ac`3ov-3vCYIP7Z?1s#$;wp-Z3A=lrhnL1 z!!Q_BgG?3wh8q}@6P5V&#Fh9pfXS8kN4#0Z=Id6VkAZ+eKllC3o0a(L;+a)(?)uNp ztX_xpoBtRV$z9k={Myp=Dpc03#9a^*nH(t>W;N3qB}(7!G?}*4tTw9jS<3!W zUVTC{6+Vp;*N{Hd*bore|$sUNh60 zF{kl9soXxuOZQqhK$m&Vq$BNT-UXshzSNzHTUe(UE*c zIjWs18)jdXN?%!-DjUex%+nB*9mV6w%7dDohKcBwjVwb?&4A&8EK&L4fF!_!T_Z;VT0{!IDGs5AkRNk5tX%;a^BlH0IMkic zehPVzf&~ys;{!*gmGK>WlpVXGJEKF&V8JdM+5ueHozPLuRPKOLOcf1P8O)M9a7YL% zr=UrpEVO80%^sJ$!72U8wL#rAFh#@OiG;LTmKP^C+GQinf z4%JZVUO`8K?19X^BnQ&P@@!rsQXr7Y7gccC9AGXTyeX*{XUiEP)1JDm@boq(r}An_ z%N6smErf1~AP8?0x%K|Z2jhgsx(EPrDzB+#!aH_E?05*^0Et-YoaVzfoCH|FiqIrf z^(e|P#d#k|Yw~S z$DL9%8_twW*qIFZR>0tN)EZb7+2rUpXzCFSC6j8(v~l5+@Q|bkeXIlVUm%$UxB(`? z_K&_SHleYwl~Roi35(cy9eKEp0TOmxe#cyXSXHzaRNWv#KVK&pgylIHgGG401x|fX zHM1$w--sr~W!9Y|{oSY%mt|2~(CzVJS|bBt&Y0PFmopx-JQfM5Irk7usdkR+Xve_B zBD z+#p@c4Mm0fx?p?+hi~ngY}?-@08#eAJwc9z9ju4$qxbYQRmpYzERcw+7r|CfaBCMI zR=U+al8D+cqQ6+(AfFn;^-N2oD0?H#cCMET+k}z3{2p0#ksd zb)yf5=iL`2%$@t&5GBrxs5>J<+Wkz799@rfKFKD#k%xwkI}+rKa2ABl+5vugSFNgQ z3zm92{P4uV3bNX*{O=JL!}bn1UKF^8Ko$hyKaCC8;Ms*A2%E)8keA>mg4`7R14!h3 ztp1GE$5?%Z)j!}TPyx~j_ONu*@N2Ygj)sS5w|s&&%8PIg#DJjCE^Hp5-N$HsfeHss z($MELJV#r;pkbSCiO~jmKfMz;k~~Pek^2K0ewqrG7G#BnPtXw9%pn|M2`4 zRW8g-nZ=Xv36tEFoG8Kza^{$(7It$PEX0_F7_$)bEX4d4VrwkK)>r^_)>I1g7zAoEaj zE#!P>#0wtwl851A(+9r*`4nn}NfInT50hF!;#Rsr>Sx%Xhs}7>Igl{20GreRlYZ@K zUjk_x!>)jI7nA-D(%npIfaj9?Xa|YUZJUSf@UR0QZD%76frOW?0679ulu1WHiZKZ) zc8`@n?@E|*@H#9pPk7CgNVBKK1HiTTPT<BD^Dt%}3(kBK{31m0FdV_LgooultmI+Qj1FJlynKI?kgS`f9L#NSEEWNLh;R~a zRTcomM~ZP+qCgftJRI@=r-ddY0beB;WwrSK&jKZIsybKl|Ca?@b8C+8e=OJ*;3(@X z`TxVBjMMA7@LK=>SGd}efSj60n}5a$x$ zo7WA^l`Y$JMTC>A&(3!5>C>lORR&(<8u5Rs`|k$-kN^MaG?~;3rR3TxW9^01cV(^K YYHKdSHP`1g*X%X7@ijO2wKx6$0?|J!Z2$lO diff --git a/numbers.c b/numbers.c index f45d131..319f4c3 100644 --- a/numbers.c +++ b/numbers.c @@ -1,3 +1,4 @@ + #include #include #include @@ -5,70 +6,135 @@ #include "numbers.h" #include "bintree.h" -// helper comparator for unsigned int for bintree +/** + * @brief Vergleichsfunktion für unsigned int-Werte zur Verwendung im Binärbaum. + * + * Diese Funktion wird von der Binärbaum-Implementierung genutzt, um die + * Ordnung der Knoten zu bestimmen. Sie vergleicht die dereferenzierten + * unsigned int-Werte a und b. + * + * @param a Pointer auf einen unsigned int-Wert (linker Operand) + * @param b Pointer auf einen unsigned int-Wert (rechter Operand) + * @return -1, falls *a < *b; 1, falls *a > *b; 0, falls *a == *b + */ static int compareUInt(const void *a, const void *b) { unsigned int va = *(const unsigned int *)a; unsigned int vb = *(const unsigned int *)b; - if(va < vb) return -1; - if(va > vb) return 1; + if (va < vb) return -1; + if (va > vb) return 1; return 0; } -// comparator for qsort (unsigned int) +/** + * @brief Vergleichsfunktion für qsort() zur Sortierung von unsigned int-Arrays. + * + * @param a Pointer auf einen Arrayeintrag + * @param b Pointer auf einen Arrayeintrag + * @return -1, 0, 1 analog zu compareUInt() + */ static int qsort_uint_cmp(const void *a, const void *b) { unsigned int va = *(const unsigned int *)a; unsigned int vb = *(const unsigned int *)b; - if(va < vb) return -1; - if(va > vb) return 1; + if (va < vb) return -1; + if (va > vb) return 1; return 0; } -// 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. +/** + * @brief Erzeugt ein Array aus len Zufallszahlen im Bereich [1 .. 2*len], + * das genau einen duplizierten Wert enthält (d. h. len-1 eindeutige + 1 Duplikat), + * und mischt die Reihenfolge zufällig. + * + * Funktionsweise: + * - Es werden zunächst len-1 eindeutige Zufallszahlen erzeugt. Die Eindeutigkeit wird + * mithilfe eines Binärsuchbaums (BST) geprüft: addToTree() fügt die Zahl ein + * und signalisiert per isDup, ob sie bereits vorhanden war. + * - Anschließend wird eine der bereits erzeugten Zahlen zufällig ausgewählt und + * noch einmal an das Ende des Arrays geschrieben, um das geforderte Duplikat sicherzustellen. + * - Zum Schluss wird das gesamte Array mittels Fisher–Yates-Algorithmus gemischt. + * + * Fehlerbehandlung: + * - Bei len < 2 wird NULL zurückgegeben, da das Problem ein Duplikat erfordert. + * - Bei Speicher- oder Baum-Insertionsfehlern wird aufgeräumt und NULL zurückgegeben. + * Wichtig: Der Baumzeiger root wird erst nach erfolgreichem Insert aktualisiert, + * um im Fehlerfall kein bereits aufgebautes Teilbaum-Objekt zu verlieren. + * + * Randbedingungen / Annahmen: + * - addToTree(root, &val, sizeof(val), compareUInt, &isDup) setzt isDup: + * isDup == 1 bedeutet „Duplikat gefunden, Baum unverändert“, + * isDup == 0 bedeutet „neuer Wert eingefügt (oder Fehler)“. + * - Bei Speicherfehler gibt addToTree NULL zurück und isDup bleibt 0. + * - clearTree(root) darf mit NULL-Argument aufgerufen werden (No-Op). + * + * Komplexität: + * - Durchschnittlich O(len * log(len)) für die len-1 Einfügungen in den BST. + * - Shuffle in O(len). + * + * @param len Anzahl der zu erzeugenden Werte (muss >= 2 sein) + * @return Pointer auf ein Array mit len Einträgen bei Erfolg; NULL bei Fehlern + */ unsigned int *createNumbers(unsigned int len) { - if(len < 2) + if (len < 2) return NULL; unsigned int *numbers = (unsigned int *)malloc(sizeof(unsigned int) * len); - if(numbers == NULL) + if (numbers == NULL) return NULL; - // seed once - srand((unsigned int)time(NULL)); + // Zufallszahlengenerator nur einmal pro Prozess initialisieren. + // Hintergrund: Wird createNumbers mehrfach schnell hintereinander gerufen, + // kann time(NULL) identische Seeds liefern und damit identische Zahlenfolgen erzeugen. + static int seeded = 0; + if (!seeded) { + srand((unsigned int)time(NULL)); + seeded = 1; + } TreeNode *root = NULL; unsigned int range = 2 * len; - // create len-1 unique numbers - for(unsigned int i = 0; i < len - 1; i++) + + // Schritt 1: len-1 eindeutige Zufallszahlen erzeugen + for (unsigned int i = 0; i < len - 1; i++) { unsigned int val; - int isDup = 0; - // try until a unique number is inserted - do + int isDup; + + // Wiederholen, bis eine wirklich neue Zahl eingefügt wurde + for (;;) { - val = (unsigned int)(rand() % range) + 1; // [1..2*len] - root = addToTree(root, &val, sizeof(val), compareUInt, &isDup); - // if addToTree returned NULL due to allocation failure, cleanup and return NULL - if(root == NULL && isDup == 0) - { + isDup = 0; // vor jedem Insert zurücksetzen, um „alte“ Werte zu vermeiden + val = (unsigned int)(rand() % range) + 1; // Wertebereich [1 .. 2*len] + + // addToTree kann bei Erfolg einen (ggf. neuen) Wurzelzeiger liefern. + // Zur Vermeidung eines Speicherlecks bei Fehlern zunächst in temp speichern. + TreeNode *newRoot = addToTree(root, &val, sizeof(val), compareUInt, &isDup); + + if (newRoot == NULL && isDup == 0) { + // Vermutlich Speicher-/Insertionsfehler: aufräumen und abbrechen free(numbers); - clearTree(root); + clearTree(root); // root zeigt noch auf den gültigen Teilbaum return NULL; } - } while(isDup); - numbers[i] = val; + + if (!isDup) { + // Einfügen war erfolgreich und der Wert ist eindeutig. + root = newRoot; + numbers[i] = val; + break; + } + // Andernfalls Duplikat: Neue Zufallszahl versuchen. + } } - // duplicate one existing random entry - unsigned int idx = (unsigned int)(rand() % (len - 1)); + // Schritt 2: Eine der bestehenden Zahlen zufällig duplizieren + unsigned int idx = (unsigned int)(rand() % (len - 1)); // Index im Bereich [0 .. len-2] numbers[len - 1] = numbers[idx]; - // shuffle array (Fisher-Yates) - for(unsigned int i = len - 1; i > 0; i--) + // Schritt 3: Fisher–Yates-Shuffle über das gesamte Array + for (unsigned int i = len - 1; i > 0; i--) { unsigned int j = (unsigned int)(rand() % (i + 1)); unsigned int tmp = numbers[i]; @@ -76,31 +142,53 @@ unsigned int *createNumbers(unsigned int len) numbers[j] = tmp; } - // free tree resources + // Aufräumen: Baum freigeben clearTree(root); return numbers; } -// Returns only the only number in numbers which is present twice. Returns zero on errors. +/** + * @brief Findet den einzigen duplizierten Wert in einem Array aus len unsigned int. + * + * Funktionsweise: + * - Es wird eine Kopie des Eingabearrays erstellt, um die Reihenfolge des + * Originalarrays nicht zu verändern. + * - Die Kopie wird mittels qsort() aufsteigend sortiert. + * - Beim Durchlauf werden benachbarte Elemente verglichen. Da genau ein Wert + * doppelt vorkommt, finden wir ihn als erstes Paar gleicher Nachbarn. + * + * Fehlerbehandlung: + * - Bei ungültigen Parametern (numbers == NULL oder len < 2) wird 0 geliefert. + * - Bei Speicherfehlern beim Kopieren ebenfalls 0. + * + * Komplexität: + * - Sortieren in O(len * log(len)), anschließender Linearpass O(len). + * + * @param numbers Pointer auf das Eingabearray + * @param len Länge des Arrays (muss >= 2 sein) + * @return Der doppelte Wert; 0 bei Fehlern oder falls kein Duplikat gefunden wurde + * (gemäß Aufgabenstellung sollte aber genau ein Duplikat existieren). + */ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) { - if(numbers == NULL || len < 2) + if (numbers == NULL || len < 2) return 0; - // make a copy so original array order is not modified by caller expectation + // Kopie erstellen, damit das Original unangetastet bleibt unsigned int *copy = (unsigned int *)malloc(sizeof(unsigned int) * len); - if(copy == NULL) + if (copy == NULL) return 0; memcpy(copy, numbers, sizeof(unsigned int) * len); + // Sortieren der Kopie qsort(copy, len, sizeof(unsigned int), qsort_uint_cmp); + // Linearer Scan: erstes Paar identischer Nachbarn ist das Duplikat unsigned int result = 0; - for(unsigned int i = 0; i + 1 < len; i++) + for (unsigned int i = 0; i + 1 < len; i++) { - if(copy[i] == copy[i+1]) - { + if (copy[i] == copy[i + 1]) { result = copy[i]; break; } @@ -108,4 +196,4 @@ unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) free(copy); return result; -} \ No newline at end of file +} diff --git a/numbers.o b/numbers.o deleted file mode 100644 index 782422483b6fc37854303ecf9fe6a227ef57da97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6253 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 diff --git a/test_numbers.c b/test_numbers.c index 067bb3b..e14e98b 100644 --- a/test_numbers.c +++ b/test_numbers.c @@ -1,41 +1,91 @@ + #include #include #include #include "numbers.h" +/** + * @brief Selbsttest für createNumbers() und getDuplicate(). + * + * Erzeugt ein Array aus len Zufallszahlen mit genau einem duplizierten Wert, + * validiert die Eigenschaften per Zähl-Array (Wertebereich, Häufigkeiten) + * und prüft anschließend, ob getDuplicate() dasselbe Duplikat ermittelt. + * + * Rückgabecodes: + * 0: OK + * 1: createNumbers() fehlgeschlagen + * 2: Speicherfehler für counts + * 3: Wert außerhalb des Bereichs [1..2*len] + * 4: Ein Wert erscheint öfter als zweimal + * 5: Nicht genau ein Duplikat gefunden + * 6: getDuplicate() liefert anderes Ergebnis als Zählung + */ int main(void) { - unsigned int len = 100; + unsigned int len = 100; // Anzahl zu erzeugender Zahlen unsigned int *nums = createNumbers(len); - if(nums == NULL) { fprintf(stderr, "createNumbers returned NULL\n"); return 1; } - - // count occurrences - unsigned int maxVal = 2 * len; - unsigned int *counts = calloc(maxVal + 1, sizeof(unsigned int)); - if(counts == NULL) { free(nums); return 2; } - - for(unsigned int i = 0; i < len; i++) - { - if(nums[i] > maxVal) { fprintf(stderr, "value out of expected range\n"); free(nums); free(counts); return 3; } - counts[nums[i]]++; + if (nums == NULL) { + fprintf(stderr, "createNumbers returned NULL\n"); + return 1; // Erzeugung fehlgeschlagen } + unsigned int maxVal = 2 * len; // Erlaubter Bereich: [1 .. 2*len] + + // Zähl-Array für Häufigkeiten pro Wert (Index 0 bleibt ungenutzt) + unsigned int *counts = calloc(maxVal + 1, sizeof(unsigned int)); + if (counts == NULL) { + free(nums); + return 2; // Speicherfehler bei counts + } + + // Häufigkeiten bestimmen und gleichzeitig Bereich prüfen + for (unsigned int i = 0; i < len; i++) { + unsigned int v = nums[i]; + if (v == 0 || v > maxVal) { // sollte nicht passieren, wenn createNumbers korrekt ist + fprintf(stderr, "value out of expected range\n"); + free(nums); + free(counts); + return 3; + } + counts[v]++; // Auftreten des Werts v zählen + } + + // Exakt ein Wert muss doppelt vorkommen; keiner darf >2-mal vorkommen int duplicatesFound = 0; unsigned int duplicateValue = 0; - for(unsigned int v = 1; v <= maxVal; v++) - { - if(counts[v] == 2) { duplicatesFound++; duplicateValue = v; } - else if(counts[v] > 2) { fprintf(stderr, "value %u appears more than twice\n", v); free(nums); free(counts); return 4; } + + for (unsigned int v = 1; v <= maxVal; v++) { + if (counts[v] == 2) { + duplicatesFound++; + duplicateValue = v; // den doppelten Wert merken + } else if (counts[v] > 2) { + fprintf(stderr, "value %u appears more than twice\n", v); + free(nums); + free(counts); + return 4; // Vertragsbruch: zu häufiges Auftreten + } + // counts[v] == 0 oder 1 sind unkritisch } - if(duplicatesFound != 1) { fprintf(stderr, "expected exactly one duplicated value, found %d\n", duplicatesFound); free(nums); free(counts); return 5; } + if (duplicatesFound != 1) { + fprintf(stderr, "expected exactly one duplicated value, found %d\n", duplicatesFound); + free(nums); + free(counts); + return 5; // zu wenige/zu viele Duplikate + } + // Ergebnis von getDuplicate() mit der Zählung abgleichen unsigned int found = getDuplicate(nums, len); - if(found != duplicateValue) { fprintf(stderr, "getDuplicate returned %u expected %u\n", found, duplicateValue); free(nums); free(counts); return 6; } + if (found != duplicateValue) { + fprintf(stderr, "getDuplicate returned %u expected %u\n", found, duplicateValue); + free(nums); + free(counts); + return 6; // Abweichung zwischen Methoden + } + // Ressourcen freigeben und Erfolg melden free(nums); free(counts); - printf("test_numbers: OK (duplicate = %u)\n", duplicateValue); return 0; } diff --git a/timer.o b/timer.o deleted file mode 100644 index 80d7bf24a1e55897ea8c0c18bd445e104a29e2c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3080 zcmbtW-D@0G6u)<7C%bi%?53M)qt;AqOs!;RH=j*YYu0Q+l8PnR1QoVjXLl#N+w9JS znc2DqDPpkF`W2s~*asg3{{x>Cqm^1kL`3=~_#%iFlz>oBjOW}tGdq)1eDJ`W`#b0S z?zvxcKS~!n3ChDNMyt#a4D>I_-fR0@{m zC&c}RgI_{kGnjBc#J-1i{gNT+jIz3$cMEtooc^^z1;#UjJZv{4`m-T#A(I*j`qn5R z-M|asKtZs`koZ(;aE#fmdKJK%A=lz1;|-?+PPFz(ge*GwpsPIJ$Y_A~E?6_bt2jJ9 z4rq7uXn=PogS9(09tiya){l_SFN`-H9Pk1VKE}p;!sg{zuzwYZcfcIK@AMCco*|j3 zrMXK#&8^>(f5!TkSc4mL>z~VKt~rr3i!8@}+uVvhviTZgfb}IK^qFfLOlU-uB10jO z!oV1Qiet=jFDei$FT>Z421@3w3@gd+pPYyFm!Kxv;_RsnStbXt3af_z1e!^&gM8AqzDqPh`~^?W)xTQHW4P{A3$#e%T`T0i%yFiihm2P zJ>IsE7?}uH66kNUY-4q?TGyc41CdiOG42GeI>Vw@(JRz7)oPep>9huOQL>2A&fITT zU{Ilw(J0h35@zi>+4{X7&do@#6527Sh)SirOp_yF_@Cjq|>p8z-}UI#?JL3I;8Dp9hB zHwTv3Po>1V)J234eMX|?rqsJG9p=^%EMDf;O{pENlTvr2TM92r`<{?`K9btMLT4LP zY{^PTlj&5HscxT8eK=pyVA zo^K-4Jc_wE!ol(=^3aNs87_arol*Awe#hw) zIBO_)=J9i{$!r{t3|rJOb`nO@J7N4BE1Y6XR;;!_Yv-I@eY~&ZzI+pit85? z|GNmIBE?k*ivLZ7_bcb%T(v~;y@xO&Qe2jM5i9r@4J{{h-0zr6qe