Studientagsübung FindeGroesstenWert

Dr Franke Ghostwriter
Studientagsübung: FindeGroesstenWert()

Die rhetorische Frage, ob noch jemand Lust hätte, die als iterative Methode durchgespielte Lösung noch "mal eben" rekursiv zu machen, wurde einstimmig abschlägig beschieden 🙂

Ich gebe ja auch zu, dass sich eine iterative Lösung hier angeboten hätte, hab's aber trotzdem lieber rekursiv gemacht.

Hier der Vorschlach, mit Aufteilung in "Türsteher und Arbeitermethode" bei der Rekursion, sowie einer Q&D Testmethode, um den in der Aufgabenstellung gegebenen Fall zu testen:

Code:
    public int findeGroesstenWert()
    {
        // Variable für Rückgabewert definieren und mit vorgegebenen 
        // Standardwert belegen
        int maxValue = Integer.MIN_VALUE;
        
        // Falls Liste leer sein sollte: Standardwert zurückgeben
        if (erstes == null) return maxValue;
        
        // ansonsten rekursive Methode aufrufen, um den tatsächlich 
        // grössten Wert zu ermitteln
        maxValue = findeGroesstenWert(maxValue, erstes);
        return maxValue;
    }
    
    /**
     * Diese Methode klappert rekursiv alle Elemente der Liste ab, und 
     * prüft den in jedem einzelnen Element gespeicherten Wert daraufhin
     * ab, ob er grösser als der aktuell grösste ist.
     * Beim Basisfall (dem letzten Element) angekommen, wird die Prüfung 
     * noch genau ein Mal durchgeführt und dann der ermittelte grösste 
     * Wert zurückgegeben
     * 
     * @param maxValue der aktuell grösste Wert
     * @param dieses Verweis auf das aktuell zu prüfende Listenelement
     * @returns den ermittelten grössten Wert
     */
    private int findeGroesstenWert(int maxValue, ListenElement dieses)
    {
        // Falls der Wert des übergebenen Elements ("dieses") grösser ist
        // als der aktuell grösste Wert der Liste, so ist das der neue
        // aktuell grösste Wert
        // (Ansonsten bleibt der aktuell grösste Wert unverändert...)
        if (dieses.wert > maxValue)
        {
            maxValue = dieses.wert;
        }
        
        // Wenn das übergebene Element nicht das Letzte der Liste war,
        // dann wiederholen wir den Grössenvergleich rekursiv
        if (dieses.naechstes != null)
        {
            // um uns dem Basisfall zu nähern rufen wir dieselbe
            // Methode nochmals auf, aber mit dem folgenden Element 
            maxValue = findeGroesstenWert(maxValue, dieses.naechstes);
        }
        
        // Hier sind wir am innersten Punkt der Rekursion angelangt
        // (Basisfall; es gibt kein nächstes Element), also können wir
        // hier das aktuelle Ergebnis rekursiv nach oben durchreichen
        return maxValue;        
    }
    
    /**
     * Q&D Testmethode
     * Stellt die in der Aufgabenstellung gegebenen Bedingungen her
     */
    public int Q_and_D_Test()
    {
        // Die folgenden Anweisungen füllen die Liste zunächst mit den
        // Werten 4, 9, 2, und 7, löschen dann den ersten Wert und fügen 
        // den Wert 3 anschliessend noch hinzu.
        // Dann soll der aktuell grösste Wert ermittelt werden, was 
        // erwartungsgemäss 9 sein sollte.
        fuegeWertHinzu(4);
        fuegeWertHinzu(9);
        fuegeWertHinzu(2);
        fuegeWertHinzu(7);
        loescheErstenWert();
        fuegeWertHinzu(3);
        return findeGroesstenWert();
    }
 
Was meinst du zu folgender Alternative (ohne Kommentare)
Code:
public int findeGroesstenWert()
{
    return findeGroesstenWert(Integer.MIN_VALUE, erstes);
}

private int findeGroesstenWert(int maxValue, ListenElement dieses)
{
    if (dieses==null) {
        return maxValue;
    }
    if (dieses.wert > maxValue)
    {
        maxValue = dieses.wert;
    }
    return findeGroesstenWert(maxValue, dieses.naechstes);
}
Wobei ich normal nicht auf die Idee kommen würde, die Aufgabenstellung rekursiv zu lösen
 
Was meinst du zu folgender Alternative

Sieht fast aus wie meins; nur deutlich kürzer.
Ich habe da ohnehin die Angewohnheit, lieber was mehr zu schreiben. Wenn ich den Code lange lange nicht gesehen habe, dann arbeite ich mich lieber Zeile für Zeile wieder rein, anstatt eine Bandwurmzeile zu sezieren.
Ich gehe auch davon aus, dass moderne Compiler das dann trotzdem laufzeitoptimal zusammenstricken können, oder dass sich ansonsten wenigstens die Verzögerung nur im Bereich von Millisekunden abspielt, die der Anwender nicht merkt.

Bei uns (C#) hätte ich da ein wenig Bedenken, den Knoten "erstes" direkt als Parameter an eine Methode weiterzureichen, wenn nicht sicher ist, ob der schon initialisiert wurde.
Ich habe in ähnlich gearteten Situationen schon mehrfach ein "Reference not set to an instance..." auf die Finger bekommen. Das tut weh, dann merkt man sich das.
Kann gut sein, dass Java da gar nicht meckert, oder?

Wobei ich normal nicht auf die Idee kommen würde, die Aufgabenstellung rekursiv zu lösen 🙂
Du weisst ja: wer neue Wege geht hinterlässt Spuren 🙂
Nee, eigentlich käme ich auch nicht dadrauf; ausser im Rahmen der Klausurvorbereitung.
Iterative Lösungen sind ja teilweise eher langweilig, oder ?
 
Sieht fast aus wie meins; nur deutlich kürzer.
Ich habe da ohnehin die Angewohnheit, lieber was mehr zu schreiben. Wenn ich den Code lange lange nicht gesehen habe, dann arbeite ich mich lieber Zeile für Zeile wieder rein, anstatt eine Bandwurmzeile zu sezieren.
Na ja, eine Bandwurmzeile ist hier aber nicht drin 🙂
Meine Variante spart im Grunde nur einen Vergleich, aber die Einsprungsroutine ist klarer finde ich.

Ich gehe auch davon aus, dass moderne Compiler das dann trotzdem laufzeitoptimal zusammenstricken können, oder dass sich ansonsten wenigstens die Verzögerung nur im Bereich von Millisekunden abspielt, die der Anwender nicht merkt.
Die Laufzeit dürfte nur minimal unterschiedlich sein, wobei ich in der Regel schon auf Laufzeit achte, da ich mit embedded Systemen zu tun habe. Allerdings ist da Rekursion eh etwas problematisch durch den Speicherbedarf.

Bei uns (C#) hätte ich da ein wenig Bedenken, den Knoten "erstes" direkt als Parameter an eine Methode weiterzureichen, wenn nicht sicher ist, ob der schon initialisiert wurde.
Ich habe in ähnlich gearteten Situationen schon mehrfach ein "Reference not set to an instance..." auf die Finger bekommen. Das tut weh, dann merkt man sich das.
Kann gut sein, dass Java da gar nicht meckert, oder?
Der Compiler liefert wenn ich mich nicht sehr täusche eine Warnung
Wobei in mener Variante das Problem mit einem nicht initalisierten Objekt abgefangen wird
if (dieses==null)
Du weisst ja: wer neue Wege geht hinterlässt Spuren 🙂
Nee, eigentlich käme ich auch nicht dadrauf; ausser im Rahmen der Klausurvorbereitung.
Iterative Lösungen sind ja teilweise eher langweilig, oder ?
Auch wieder wahr
 
Oben