EINI, Lösungen Übungsblatt 11 11.2 1 2 Listen public class Liste { private Element kopf; 3 public Liste(){ kopf = null;} 4 5 public void einfuegenVorn(int wert){ Element neu = new Element(wert); neu.weiter = kopf; kopf = neu; } 6 7 8 9 10 11 public void gibAlleAus(){ Element aktuell = kopf; while(aktuell != null){ System.out.println(aktuell.wert + " "); aktuell = aktuell.weiter; } } 12 13 14 15 16 17 18 19 public boolean istLeer(){ if(kopf == null) return true; else return false; } 20 21 22 23 24 25 26 public int anzahl(){ int anzahl = 0; Element aktuell = kopf; while(aktuell != null){ anzahl++; aktuell = aktuell.weiter; } return anzahl; } 27 28 29 30 31 32 33 34 35 36 public Element letztesElement(){ Element aktuell = kopf; while(aktuell.weiter != null){ aktuell = aktuell.weiter; } return aktuell; } 37 38 39 40 41 42 43 44 // zum Testen: public static void main(String[] args){ Liste L = new Liste(); System.out.println("Liste leer? : " + L.istLeer()); // Ausgabe: Liste leer? : true L.einfuegenVorn(2); L.einfuegenVorn(3); L.einfuegenVorn(1); System.out.println("Liste leer? : " + L.istLeer()); // Ausgabe: Liste leer? : false L.gibAlleAus(); // Ausgabe: 1 3 2 System.out.println("Wert des letzten Elements: " + L.letztesElement().wert); // Ausgabe: Wert des letzten Elements: 2 } 45 46 47 48 49 50 51 52 53 54 55 56 57 } 1 EINI, Lösungen Übungsblatt 11 11.3 Baumdurchlauf a) Die Methode ausgeben(Knoten k) entspricht der Post-Order-Iteration (LRw) über einem Baum, da zuerst der linke Teilbaum, dann der rechte Teilbaum und danach die Wurzel ausgegeben wird. b) Pre-Order: 3 4 6 8 7 2 0 5 9 1 w L R 3 w L R 4 w L R 2 w L R 6 x x w L R 8 x w L R 0 x x w L R 5 w L R 7 x x w L R 9 x x w L R 1 x x c) Post-Order: 6 7 8 4 0 9 1 5 2 3 L R w 3 L R w 4 L R w x x 6 L R w x 8 L R w 2 L R w x x 0 L R w x x 7 L R w 5 L R w x x 9 L R w x x 1 d) In-Order: 6 4 8 7 3 0 2 9 5 1 L w R 3 L w R 4 L w R x 6 x L w R 2 L w R x 8 L w R x 7 x L w R x 0 x L w R 5 L w R x 9 x 2 L w R x 1 x EINI, Lösungen Übungsblatt 11 11.4 1 2 Klasse Heap [Iterative Lösung] class Heap { int[] array; // Stelle 0 speichert die Anzahl der Elemente 3 4 5 6 Heap(int kapazitaet){ array = new int[kapazitaet+1]; } 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 int entferneMinimum(){ // Wenn heap leer gib "null" zurueck if(istLeer()) return 0; // Wenn heap nur ein Element hat gib es zurueck if(array[0] == 1) {array[0]--; return array[1];} int min = array[1]; int aktuell = array[array[0]]; int aktuellStelle = 1; int linkerSohnStelle = aktuellStelle*2; int rechterSohnStelle = aktuellStelle*2+1; // Solange die aktuelle Stelle kein Blatt ist while(aktuellStelle <= array[0]/2){ // Wenn es nur linken Sohn gibt if(rechterSohnStelle > array[0]-1){ // Wenn aktuell >= linkerSohn if(aktuell >= array[linkerSohnStelle]){ // Vertausche aktuell mit linker Sohn int x = array[linkerSohnStelle]; array[linkerSohnStelle] = aktuell; array[aktuellStelle] = x; } // Da es keine weiteren Knoten gibt, // mit denen aktuell Vertauscht werden koennte, // koennen wir abbrechen. break; } else { // Es gibt sowohl linken als auch rechten Sohn // Wenn linker Sohn < rechter Sohn if(array[linkerSohnStelle] < array[rechterSohnStelle]){ // Vertausche aktuell mit linkem Sohn int x = array[linkerSohnStelle]; array[linkerSohnStelle] = aktuell; array[aktuellStelle] = x; // setze aktuelle Stelle auf Stelle des linken Sohnes aktuellStelle = linkerSohnStelle; } else { // rechter Sohn < linker Sohn // Vertausche aktuell mit rechtem Sohn int x = array[rechterSohnStelle]; array[rechterSohnStelle] = aktuell; array[aktuellStelle] = x; // setze aktuelle Stelle auf Stelle des rechten Sohnes aktuellStelle = rechterSohnStelle; } // Aktuallisiere die Stellen der Soehne linkerSohnStelle = aktuellStelle*2; rechterSohnStelle = aktuellStelle*2+1; } } array[0]--; return min; } 3 EINI, Lösungen Übungsblatt 11 void einfuegen(int zahl){ // kehre zurueck wenn kein freier Platz im Array vorhanden // alternativ mit if(array[0]+1 != array.length) {...} if(array[0]+1 == array.length) return; // erhoehe die Anzahl der Elemente um 1 array[0]++; // speichere die zahl an die naechste freie Stelle array[array[0]] = zahl; // setze diese Stelle als SohnKnotenStelle int sohnStelle = array[0]; // bereche die Stelle seines VaterKnotens int vaterStelle = array[0]/2; // Solange ein SohnKnoten < sein VaterKnoten und SohnStelle != 1 while(array[sohnStelle] < array[vaterStelle] && sohnStelle != 1){ // Vertausche SohnKnoten mit VaterKnoten int x = array[vaterStelle]; array[vaterStelle] = array[sohnStelle]; array[sohnStelle] = x; // Ersetze SohnStelle mit VaterStelle sohnStelle = vaterStelle; // und berechne neue VaterStelle vaterStelle = sohnStelle/2; } } 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 boolean istLeer(){ if(array[0] == 0) return true; else return false; } 84 85 86 87 88 89 90 } 11.5 a) 1 2 3 4 class Mensch { private int geburtsjahr; private float groesse; private boolean geschlecht; 5 Mensch(int geburtsjahr, float groesse, boolean weiblich){ this.geburtsjahr = geburtsjahr; this.groesse = groesse; this.geschlecht = weiblich; } 6 7 8 9 10 11 public void setzeGroesse(float gross){ groesse = gross; } 12 13 14 15 public int gibAlter(int aktuellesJahr){ return aktuellesJahr - geburtsjahr; } 16 17 18 19 } 4 EINI, Lösungen Übungsblatt 11 b) (i) Mensch maedchen = new Mensch(2000, 0.52, true); (ii) maedchen.setzeGroesse(1.2); (iii) System.out.println("Mädchen ist im Jahr 2006 " + maedchen.gibAlter(2006) + "Jahre alt")); c) class Mensch extends Lebewesen {...} 11.6 1 2 3 class Produkt { private double preis; private int aufLager; 4 public Produkt(double preis){ this.preis = preis; aufLager = 0; } 5 6 7 8 9 public double getPreis(){ return preis; } 10 11 12 13 public void einkaufen(int anzahl){ aufLager = anzahl; } 14 15 16 17 public boolean verkaufen(int anzahl){ if(anzahl > aufLager) return false; else aufLager -= anzahl; return true; } 18 19 20 21 22 23 24 25 } d) Produkt sackMehl = new Produkt(5.99); Produkt ei = new Produkt(0.10); sackMehl.einkaufen(10); ei.einkaufen(800); e) private und public sind Java-interne Schlüsselwörter, die Zugriffsberechtigungen von Klassenattributen und Klassenmethoden steuern. Bei public dürfen Attribute und Methoden auch außerhalb der Klasse, in der diese stehen, benutzt werden. Bei private ist der Zugriff nur auf die Klasse selbst, in der die privaten Attribute und Methoden stehen, beschränkt. Steht vor einem Attribut bzw. einer Methode keines der beiden Schlüsselwörter, so wird es in Java als public behandelt. 5