Variablen und Referenzen Stapel (Stack, Keller) Eine wichtige Datenstruktur ist der Stapel. Das Prinzip, dass das zuletzt eingefügte Element als erstes wieder entfernt werden muss, bezeichnet man als LIFO-Prinzip (last-in, first-out). Stacks sind z.B. bei der syntaktischen Analyse (Compiler), bei der Berechnung von arithmetischen Termen oder bei der Abarbeitung von Rekursionen von zentraler Bedeutung. Wir stellen uns den Stapel als spezielle Liste vor, bei der Elemente nur am Anfang (= oben) hinzufügen können. Ein Zugriff ist nur auf das oberste Element möglich. Ein Stapel kann man sich mit einem Münzstapel vorstellen, bei dem Münzen oben aufgelegt oder entfernt werden können. Der ADT Stapel in Java Konstruktor Stack( ) Bedeutung: Neuer Stapel (Stapel ist leer) Attribut-Methoden boolean isEmpty() true, wenn Stapel leer Object peek() liefert das oberste Element, ohne den Stapel zu verändern (= Inspizieren der Stapelspitze) Modifizierende Methoden Object push (Object element) legt ein Element oben auf den Stapel und gibt element als Rückgabe zurück Object pop( ) Die Operation entfernt das oberste Element; Fehler, wenn Stapel leer Beispiel Stack s = new Stack(); s.isEmpty(); true s.push("a"); s.isEmpty(); false s.peek( ); "a" s.pop( ); "a" s.isEmpty(); liefert jetzt true; s.pop( ) führt zu einer Fehlermeldung s.peek() führt zu einer Fehlermeldung © Wagner, Apr-11 Seite 27 Variablen und Referenzen Aufgabe: Was liefern folgende Operationen? Stack s; s.isEmpty(); s = new Stack(); s.isEmpty(); s.push ("x"); s.peek(); s.push("z"); s.pop(); s.push("y"); s.isEmpty(); s= new Stack(); s.pop(); Programmierung des ADT Stapel (als spezielle lineare Liste) public interface StapelIF { public boolean isEmpty(); //TRUE, wenn Stapel leer public Object push(Object e); // Legt Knoten auf Stapel public Object pop(); // Entfernt oberstes Element vom Stapel public Object peek(); // Oberstes Stapelelement lesen public String toString(); // Gibt Stapel aus } // Interface public class Stapel implements StapelIF { private Knoten top; // Konstruktor: Stapel() { top=null; } public boolean isEmpty() { //TRUE, wenn Stapel leer if (top == null) return true; else return false; } public Object push(Object element) { Knoten k = new Knoten(element,null); if (top == null) top = k; else { k.setzeNachfolger(top); top=k; } return element; } // push © Wagner, Apr-11 Seite 28 Variablen und Referenzen public Object pop() { if (top != null) { Object ergebnis=top.liefereElement(); top= top.liefereNachfolger(); return ergebnis; } else return null; } // pop public Object peek() { if (top != null) { Object ergebnis = top.liefereElement(); return ergebnis; } else return null; } // peek public String toString() { String s=""; Knoten x = top; while(x != null) { s = s+x.liefereElement().toString()+"\n"; x= x.liefereNachfolger(); } return s; } // toString } © Wagner, Apr-11 Seite 29 Variablen und Referenzen Das Applet StapelTest (in Auszügen) Stapel stapel = new Stapel(); …. Der Button PUSH protected void jButton1ActionPerformed(ActionEvent evt){ //TODO add your handler code here String ein = jTextField1.getText(); stapel.push(ein); jTextArea1.setText(stapel.toString()+"\n===="); jTextArea2.append("PUSH: "+ein+"\n"); jTextField1.requestFocus(); // Textfeld erhält Fokus jTextField1.selectAll(); // alles markieren } // PUSH Der Button POP protected void jButton2ActionPerformed(ActionEvent evt){ if (!stapel.isEmpty()) { jTextArea2.append("POP: "+stapel.pop()+"\n"); } else { jTextArea2.append("Stapel leer\n"); } jTextArea1.setText(stapel.toString()+"\n===="); } // POP Der Button Peek private void jButton3ActionPerformed(ActionEvent evt) { jTextArea2.append("Peek: "+stapel.peek()+"\n"); jTextArea1.setText(stapel.toString()+"\n===="); } // Peek © Wagner, Apr-11 Seite 30 Variablen und Referenzen Fragen & Aufgaben Warum entsteht bei der späteren Verwendung des Stapels eine Fehlermeldung, wenn in der Deklaration statt Stapel stapel = new Stapel(); die falsche Anweisung Stapel stapel = null; steht? Aufgabe Entferne in der Klasse die Methode toString() durch Auskommentieren. Die Anwendung StapelTest läuft weiterhin, da die Klasse Object eine gleichlautende Methode bereitstellt! Allerdings erzeugt sie eine völlig andere Ausgabe: Jede Klasse, die sich auf die Klasse Object stützt, verfügt automatisch über eine Methode toString(). Die Implementierung in Object liefert einen String der Art Klassenname@Referenz. © Wagner, Apr-11 Seite 31