Links und Funktionen
Sprachumschaltung

Navigationspfad


Inhaltsbereich

baum_kompositum_turtle.py

Python Source icon baum_kompositum_turtle.py — Python Source, 9 KB (9818 bytes)

Dateiinhalt

# Implementation Binärer Suchbaum
# Design Pattern: Kompositum
# features: suchen(), einfügen(), __str__(), gibGrößtes/Kleinstes(),
# Durchläufe: inOrder(), preOrder(), postOrder()
# gibHoehe(), gibTiefe(Knoten), gibKnotenZahl(), speichern(), laden()
# grafik() = Turtle-Grafik

from turtle import *                       # Turtle-Grafik

class Knotenelement(object):
    "abstrakte Klasse für Knoten und Abschluss eines binären Baumes"
    def __init__(self, element, lnach, rnach):
        "Konstruktor"
        self.element=element
        self.lnach = lnach
        self.rnach = rnach

  
class Abschluss(Knotenelement):             # 'pro forma'-Vererbung
    "Modelliert Blätter des Binärbaumes"
    def __init__(self):
        "Konstruktor"
        pass                                # tu' nix 
    
    def einfügen(self, neuKnot, altKnot):
        "Blatt einfügen"
        if neuKnot < altKnot.element:       # falls neues Element kleiner...
            altKnot.lnach = Knoten(neuKnot)
        else:                               # falls neues Element größer ...
            altKnot.rnach = Knoten(neuKnot)
        return True
  
    def inOrder(self):                      # tritt nicht in Erscheinung
        "keine Information, da leer"
        pass

    def preOrder(self):                     # tritt nicht in Erscheinung
        "keine Information, da leer"
        return ""

    def postOrder(self):                    # tritt nicht in Erscheinung
        "keine Information, da leer"
        pass

    def suchen(self, vergleich):            
        "gibt NICHTS zurück"
        return False

    def restKnotenZahl(self):
        "gibt Null zurück"
        return 0

    def __str__(self):
        return "-"

    def gibKleinstes(self, altKnot):
        "gibt kleinstes Element zurück"
        return altKnot.element
    
    def gibGrößtes(self, altKnot):
        "gibt größtes Element zurück"
        return altKnot.element

    def gibHöhe(self):
        "gibt Hoehe -1 zurück"
        return -1

    def gibTiefe(self,elem):
        "gibt False für nicht enthaltenes Datenelement zurück"
        return False

    def grafik(self,schrittweite):
        "löscht den Ast (die 3 letzten turtle-Befehle) zu diesem Abschluss"
        undo();undo();undo()



class Knoten(Knotenelement):
    "modelliert Knoten des Binärbaums"
    def __init__(self, element, lnach=Abschluss(), rnach=Abschluss()):
        Knotenelement.__init__(self, element, lnach, rnach) # Aufruf OKl.konstr.

    def __str__(self):
        return self.element                     # gib Element auf Konsole aus

    def gibGrößtes(self, altKnot):
        "kleinster Knoten im Teilbaum"
        return self.rnach.gibGrößtes(self)

    def gibKleinstes(self, altKnot):
        "größter Knoten im Teilbaum"
        return self.lnach.gibKleinstes(self)
        
    def einfügen(self, neuKnot, altKnot):
        "neues Element einfügen"
        if neuKnot == self.element:                     # vergleiche mit eig. Element... 
            print("Element schon vorhanden!")
            return False
        if neuKnot < self.element:                      # falls neues Element kleiner... 
            return self.lnach.einfügen(neuKnot, self)  # dann rek. Aufruf links
        else:
            return self.rnach.einfügen(neuKnot, self)  # dann rek. Aufruf rechts

    def inOrder(self):
        "Element sortiert ausgeben"
        self.lnach.inOrder()
        print(self.element, end=' ')
        self.rnach.inOrder()

    def preOrder(self):
        """Elemente als Zeichenkette mit Zeilenumbruch
zur Serialisierung des Baumes für Dateiablage"""
        print(self.element, end=" ")
        self.lnach.preOrder()
        self.rnach.preOrder()

    def postOrder(self):
        "Element ausgeben"
        self.lnach.postOrder()
        self.rnach.postOrder()
        print(self.element, end=" ")

    def suchen(self, vergleich):
        "Suche nach Zeichenkette"
        if self.element == vergleich:           # ist meine Element das Gesuchte?
            return True                         # ...gib Erfolgsmeldung zurück
        elif self.element <  vergleich:         # ist das Gesuchte größer...
            return self.rnach.suchen(vergleich) # ...suche im r. Teilbaum weiter
        else:                                   # ist das Gesuchte kleiner...
            return self.lnach.suchen(vergleich) # ...suche im l. Teilbaum weiter

    def restKnotenZahl(self):
        "gibt Anzahl der Knoten zurück"
        return self.lnach.restKnotenZahl()+self.rnach.restKnotenZahl()+1  

    def gibHöhe(self):
        "gibt größere Teilbaumhöhe zurück"
        gHl = self.lnach.gibHöhe()
        gHr = self.rnach.gibHöhe()
        if gHl >= gHr:
            return self.lnach.gibHöhe()+1
        else:
            return self.rnach.gibHöhe()+1
        
    def gibTiefe(self,elem):
        "gibt Tiefe eines Knotens(elem) zurück"
        if self.element == elem:
            return 0
        elif self.element < elem:
            return self.rnach.gibTiefe(elem)+1
        else:
            return self.lnach.gibTiefe(elem)+1

    def grafik(self,schrittweite,farbeLinks="red", farbeRechts="blue"):
        "gibt Knoten als Turtle-Grafik aus"
        pencolor("black")                   # Stiftfarbe 
        write(self.element,align='left',
              font=('Arial',12,'bold'))     # Ausgabe Element + Schriftormatierung 
        pencolor(farbeLinks)                # Stiftfarbe 'rot' für linken Ast
        ort = pos()                         # Ortskoordinaten zwischenspeichern
        right(45)                           # Rechtsschwenk für l. Ast
        fd(schrittweite)                    # l. Ast auslaufen
        left(45)                            # Linksschwenk in Senkrechte
        self.lnach.grafik(schrittweite*0.5) # lnach zeichnen...
        penup()                             # Stift hoch
        setpos(ort)                         # Ursprungsort aufsuchen
        pendown()                           # Stift runter
        pencolor(farbeRechts)               # Stiftfarbe 'blau' für r. Ast
        left(45)                            # Turtle Linksschwenk f. r. Ast
        fd(schrittweite)                    # r. Ast auslaufen
        right(45)                           # Rechtsschwenk in Senkrechte
        self.rnach.grafik(schrittweite*0.5) # rnach zeichnen...
        setpos(ort)                         # Ursprungsort aufsuchen

class Baum(object):
    """Klasse implementiert binären Baum"""
    def __init__(self, neuKnot):
        "erzeuge Binärbaum mit Wurzel [string]"
        self.wurzel = Knoten(neuKnot)
        print("Neuer Baum erzeugt")

    def __str__(self):
        return self.inOrder()
        
    def einfügen(self, neuKnot):
        "Einfügen eines Knoten am Ende (ws)"
        self.wurzel.einfügen(neuKnot, self)
               
    def inOrder(self):
        "liste alle Knoten in sortierter (Haupt-)Reihenfolge"
        self.wurzel.inOrder()

    def preOrder(self):
        "liste alle Knoten in symmetrischer Reihenfolge"
        return self.wurzel.preOrder()

    def postOrder(self):
        "liste alle Knoten in Nebenreihenfolge"
        self.wurzel.postOrder()

    def speichern(self, dateiname='binbaum.txt'):
        "Baum in Datei 'baum.txt' speichern"
        datei = open(dateiname,"w")
        datei.write(self.preOrder())
        datei.close()
        print("Baum gespeichert!")

    def laden(self, dateiname="baum.txt"):
        "Baum aus Datei laden"
        try:
            datei = open(dateiname)
            knotenliste = datei.readlines()
            baum = Baum(knotenliste[0][:-1])
            for i in knotenliste[1:]:
                baum.einfügen(i[:-1])
            return baum
        except:
            print("Datei nicht vorhanden")

    def suchen(self,vergleich):
        "Suche nach Zeichenkette"
        return self.wurzel.suchen(str(vergleich))

    def knotenZahl(self):
        "gibt Anzahl der Knoten im Baum"
        return self.wurzel.restKnotenZahl()

    def gibKleinstes(self):
        "gibt kleinstes Element zurück"
        return self.wurzel.gibKleinstes(self)

    def gibGrößtes(self):
        "gibt größtes Element zurück"
        return self.wurzel.gibGrößtes(self)

    def gibHöhe(self):
        "gibt Höhe des Baums zurück"
        return self.wurzel.gibHöhe()

    def gibTiefe(self,elem):
        "gibt Tiefe eines Knotens aus"
        if self.suchen(str(elem)):
            return self.wurzel.gibTiefe(str(elem))

    def grafik(self,farbe="black"):
        "Baum mittels Turtle-Grafik visualisieren"
        reset()                         # Zeichenfenster + Turtle auf Anfang
        title("Binärbaum 'Max&Moritz'") # Benenne Turtle-Fenster
        bgpic("MaxMoritz.gif")          # Hintergrundbild f. Fenster
        shape("classic")                # klassisches Turtle-Symbol
        pencolor(farbe)                 # Stiftfarbe
        pensize(2)                      # Stiftdicke
        speed(4)                        # Geschwindigkeit auf "mittelschnell"
        delay(20)                       # Verzögerung festlegen
        right(90)                       # Orientierung Turtle nach unten
        self.wurzel.grafik(200)         # Grafik-Funktion auf Wurzelknoten aufrufen
        ht()                            # verstecken
    
    
if __name__=="__main__":                # Falls Skript als Hauptprogramm ausgeführt..
    b = Baum("Fritz")                   # erzeuge Baum
    b.einfügen("Boeck")                 # füge Knoten hinzu...
    b.einfügen("Mecke")
    b.einfügen("Baecker")
    b.einfügen("Bolte")
    b.einfügen("Max")
    b.einfügen("Moritz")
    
    b.grafik()                          # zeichne Baum

Funktionsleiste