I2_Projects/I2_Dobble/bintree.md
2025-12-05 14:43:44 +01:00

6.2 KiB

  1. static StackNode *iteratorStack = NULL -> Stack für nextTreeData -> wird verwendet um nach und nach die Zahlen von klein nach groß auszugeben -> muss da so stehen, weil ansonsten nextTreeData immer von vorne anfängt

  2. addToTree -> soll ein Element an die richtige Stelle im Baum hinzufügen -> wenn keine root angegeben ist (wenn entweder kein Baum vorhanden ist, oder die richtige Stelle gefunden wurde) soll ein neue Node erstellt werden. -> Speicher reservieren -> data nach newNode.data kopieren (memcpy) kopiert einfach nur den Inhalt ohne ihn zu interpretieren -> pointer links und rechts werden NULL gesetzt, da keine anderen Datan vorhanden sind -> isDublicate = 0, da kein Dublikat vorhanden sein kann

    -> root.data wird mit data verglichen (größer, kleiner, gleich), um zu entscheiden, ob rechts oder links eingefügt werden soll -> gleich -> Dublikat -> einfügen verhindern -> größer -> rechts einfügen -> kleiner -> links einfügen

    -> eingefügt wird, in dem addToTree erneut aufgerufen wird, aber jetzt als root root.left/root.right übergeben wird -> es wird erneut verglichen und wieder in den rechten, bzw. linken Teilbaum eingefügt, solange bis richtige Stelle im Baum erreicht ist -> einfügen des Wertes

  3. nextTreeData -> soll nacheinander die Werte des Binärbaums der größe nach ausgeben -> Diese Funktion beruht auf einem richtigen Binär Baum (werte stehen an der richtigen Stelle) -> dabei wird der iteratorStack verwendet, auf diesem sind immer Teilbereiche unseres Binärbaums vorhanden (in sortierter Reihenfolge), allerdings ist er nie vollständig, sondern wird im laufe des Programms immer durch fehlende Werte ergänzt

    -> wenn root != NULL -> neuer Beginn bei einem ggf. anderen Baum -> iteratorStack wird gelöscht um eventuelle "Rückstände" zu beseitigen -> danach werden erstmal immer die jeweils linken Nodes in den Stack gepusht -> im Stack liegt nun die kleinste Node ganz oben, danach werden die Werte immer größer, allerdings fehlen noch Werte dazwischen

    -> anschließend wird sich die oberste Node aus dem Stack geholt und aus dem Stack entfernt -> Die ist der kleinste Wert im Baum und soll somit auch als erste zurückgegeben werden -> jetzt wird auf dem Stack der rechte Teilbaum von unseren kleinsten Wert im Baum auf den Stack gepusht -> diese Werte sind alle größer als unsere Node, jedoch kleiner als die davor vorletzte Node im Stack -> DER STACK IST ALSO IMMER NOCH NACH DER GRÖßE SORTIERT -> unser Stack hat jetzt den nächst größeren Wert im Baum als top Node -> ausgangssituation für nächsten Aufruf -> gepeicherte node wird verwendet um node.data auszugeben

                 Beispiel Baum:
    
                             12
                            /  \
                           8    15
                         /  \     \
                        5    9     17
                                 /   \
                                16   20
    
                 1) erst alle linken Nodes pushen -> 5
                                                     8
                                                     12
    
                 2) top Node (5) speichern und aus Stack entfernen -> 8 
                                                                      12
    
                 3) rechte Node und alle jeweils linken Nodes pushen -> 8
                                                                        12
                 4) -> 5 wird ausgegeben (gepeicherte Node)
                 5) neuer Aufruf
                     6) top Node speichern (8) und aus Stack entfernen -> 12
                     7) rechte Node und alle jeweils linken Nodes pushen -> 9
                                                                            12
                     8) -> 8 wird ausgegeben (gespeicherte Node)
                 9) neuer Aufruf
                     10) top Node speichern (9) und aus Stack entfernen -> 12
                     11) rechte Node und alle jeweils linken Nodes pushen -> 12
                     12) ->  9 wird ausgegeben (gespeicherte Node)
                 13) neuer Aufruf
                     14) top Node speichern (12) und aus Stack entfernen -> NULL
                     15) rechte Node und alle jeweils linken Nodes pushen -> 15
                     16) -> 12 wird ausgegeben (gespeicherte Node)
                 17) neuer Aufruf
                     18) top Node speichern (15) und aus Stack entfernen -> NULL
                     19) rechte Node und alle jeweils linken Nodes pushen -> 16
                                                                             17
                     20) -> 15 wird ausgegeben (gespeicherte Node)
                 21) neuer Aufruf
                     22) top Node speichern (16) und aus Stack entfernen -> 17
                     23) rechte Node und alle jeweils linken Nodes pushen -> 17
                     24) -> 16 wird ausgegeben (gespeicherte Node)
                 25) neuer Aufruf
                     26) top Node speichern (17) und aus Stack entfernen -> NULL
                     27) rechte Node und alle jeweils linken Nodes pushen -> 20
                     28) -> 17 wird ausgegeben (gespeicherte Node)
                 29) neuer Aufruf
                     30) top Node speichern (20) und aus Stack entfernen -> NULL
                     31) rechte Node und alle jeweils linken Nodes pushen -> NULL
                     32) -> 20 wird ausgegeben (gespeicherte Node)
                 33) neuer Aufruf -> Stack = NULL -> fertig
    
  4. treeSize -> rekursiver Aufruf der Funktion

    -> es wird jeweils die jeweils linke und rechte Node als neue root genommen -> aufruf mit treeSize(root->left / root -> right) -> es wird pro aufruf +1 gerechnet -> am Ende wird die Node Anzahl zurückgegeben