Algorithmen und Datenstrukturen - IFIS Uni Lübeck

Werbung
Prof. Dr. V. Linnemann
Universität zu Lübeck
Institut für Informationssysteme
Lübeck, den 20. Juli 2010
Algorithmen und Datenstrukturen
Sommersemester 2010
1. Klausur Lösungen
Lösung 1: Laufzeitstack
Wir nehmen an, dass die main - Methode der folgenden Klasse aufgerufen wird. Was bewirkt die main - Methode ? Geben Sie den Laufzeitstack jeweils zu Beginn eines Aufrufs
der Methode fastfibrek an. Verwenden Sie als Bezeichnung der Rückkehradressen den
jeweils angegebenen Kommentar.
public class Fiblinearrekursiv
{
public static long fastfibrek
(int nminusiplus1, long fibi, long fibiminus1) {
/* Laufzeitstack hier */
if(nminusiplus1==1)
// i==n
return fibi;
return
fastfibrek(
nminusiplus1-1,fibi+fibiminus1,fibi) /* B */;
}
public static void main(String[] args){
long ergebnis = fastfibrek(5,1,0) /* A */;
System.out.println(ergebnis);
}
}
(6 Punkte)
Lösung: Es wird die 5. Fibonacci-Zahl ausgegeben, d.h. es wird der Wert 5 ausgegeben.
1/20
Laufzeitstack:
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
5
1
0
A
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
5
1
0
A
4
1
1
B
3
2
1
B
2
3
2
B
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
2/20
5
1
0
A
4
1
1
B
3
2
1
B
2
3
2
B
1
5
3
B
5
1
0
A
4
1
1
B
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
Ergebnis
nminusiplus1
fibi
fibiminus1
Rückkehradresse
5
1
0
A
4
1
1
B
3
2
1
B
Lösung 2: Adjazenzmatrix und Backtracking mit Rekursion
a.)
Zeichnen Sie den durch die folgende Adjazenzmatrix A gegebenen gerichteten Graphen,
wobei T den Wert true bezeichnet und die false - Werte der Übersicht halber hier leer dargestellt sind. A[i][j] == true bedeutet, dass im Graphen ein Pfeil von i nach j existiert.
A
0
1
2
3
4
5
6
7
8
0
T
1
T
T
2
3
T
T
T
T
T
4
5
T
T
T
T
T
6
7
8
(3 Punkte)
T
T
T
T
T
T
T
b.)
In dieser Teilaufgabe sollen Sie einen Weg in einem durch eine Adjazenzmatrix beschriebenen gerichteten Graphen von einem Startknoten zu einem Zielknoten rekursiv mit Backtracking finden. Die Knoten sind beginnend bei 0 durchnummeriert. Es genügt, einen Weg
zu finden, die Angabe des kürzesten Weges ist hier nicht gefordert. Realisieren Sie in der
nachfolgenden Klasse die Methode probieren.
In der Methode matrix1 wird das Feld matrix mit der Adjazenzmatrix aus Aufgabenteil
a.) gesetzt.
Im Beispiel ist ein Weg vom Knoten 0 zum Knoten 8 gesucht. Hier gibt es nur einen Weg
ohne Zyklen, der offenbar durch die Knotenfolge
013578
beschrieben wird.
In der nachfolgenden Klasse gibt es für zyklenfreie Wege im Graphen ein Feld weg, das so
viele Elemente hat wie der Graph Knoten besitzt. Die Variable weglaenge gibt an, wie lang
ein aktuell gefundener Weg ist, d.h. wie viele Elemente des Feldes weg gesetzt sind.
Ihre rekursive probieren - Methode soll das Feld weg und die Variable weglaenge geeignet setzen, d.h. für das Beispiel soll weg mit den obigen Werten gefüllt und die Variable
weglaenge mit dem Wert 6 gesetzt werden..
Achten Sie darauf, dass Ihre probieren-Methode Zyklen im Graphen geeignet behandelt
und dass sie auch den Fall abdeckt, dass es keinen Weg vom Startknoten zum Zielknoten
gibt.
Erläutern Sie Ihre Lösung durch geeigneten Kommentar, so dass der Algorithmus ersichtlich
ist.
3/20
Hinweis zum Aufwand: Es gibt eine Lösung, die einschließlich Kommentar nur 27 Zeilen
enthält.
public class Labyrinth
{
// Adjazenzmatrix fuer den Graphen
private static boolean matrix[][];
// Anzahl der Knoten im Graphen
private static int knotenzahl;
// bisher gefundener Weg
private static int[] weg;
// Laenge des bisher gefundenen Weges, d.h.
// weg ist bis weg[weglaenge-1] gesetzt
private static int weglaenge;
// Startknoten fuer Wegsuche
private static int start;
// Zielknoten fuer Wegsuche
private static int ziel;
/**
* probieren sucht einen Weg bis zum Zielknoten
* ausgehend von knoten.
*
* weglaenge und weg enthalten bei Aufruf einen Weg
* zu einem Vorgaengerknoten von knoten, d.h. der
* Knoten ist bei Aufruf noch n i c h t in weg abgelegt.
* Beim ersten Aufruf, d.h. wenn knoten der Startknoten ist,
* enthaelt weglaenge den Wert 0
*
* @param knoten Knoten, von dem aus ein Weg
gesucht werden soll
*
*
* @return true: Weg wurde gefunden, weg und weglaenge
enthalten die Knoten des Weges,
*
false: es gibt keinen Weg
*
*/
private static boolean probieren ( int knoten ) {
// Diese Methode ist im Rahmen der Aufgabe zu formulieren
}
4/20
private static void matrix1(){
boolean[][] m =
{
{ true, true, false,false,false,false,false,false,false},
{ false,true, true, true, false,false,false,false,false},
{ false,false,true, false,false,false,false,false,false},
{ false,false,false,true, true ,true, false,false,false},
{ false,true, false,false,true, false,false,false,false},
{ false,false,false,false,false,true, true, true, false},
{ false,false,false,false,false,true, true, false,false},
{ false,false,false,false,false,false,true, true, true },
{ false,false,false,false,false,false,false,false,true }
};
matrix = m;
start = 0;
ziel = 8;
}
public static void main(String[] args){
matrix1();
knotenzahl=matrix.length;
weg = new int[knotenzahl];
weglaenge=0;
// Der bisher gefundene Weg ist leer
if (probieren(start)){
for (int i=0; i<weglaenge; i++)
System.out.print(weg[i]+"
");
System.out.println();
} else{
System.out.println(
"Es gibt keinen Weg von "+start+" nach "+ziel);
}
}
}
(20 Punkte)
Lösung:
a.)
5/20
0
1
3
5
2
4
6
7
8
b.)
private static boolean probieren ( int knoten ) {
// Ueberpruefen, ob der Knoten bereits besucht wurde
for(int i=0; i<weglaenge; i++)
if (knoten == weg[i]) return false;
// Knoten zum Weg hinzufuegen
weglaenge++;
weg[weglaenge-1] = knoten;
if (knoten == ziel) return true;
// ziel noch nicht erreicht,
// d.h. alle vom Knoten direkt erreichbaren
// Knoten probieren
for (int i=0; i<knotenzahl; i++) {
if (matrix[knoten][i]) {
if (probieren(i)) return true;
}
}
// Sackgasse, d.h. Knoten vom Weg wieder entfernen
// Alle Werte und Felder haben den gleichen Zustand wie
// bei Aufruf
weglaenge--;
return false;
}
Lösung 3: Heapsort
Gegeben sei die Folge 37,79,11,28,90,36,21,33,99, die in einem Array vorliegt. Sortieren Sie das Array mit Heapsort. Bauen Sie dafür zunächst den Heap auf. Zeichnen Sie für
6/20
den Aufbau des Heaps geeignete Zwischenschritte und den entstandenen Heap. Zeichnen
Sie anschließend den Heap und den bereits sortierten Teil des Feldes jedesmal, wenn das
getauschte Element eingesunken ist. Zeichnen Sie den Heap der Übersicht halber jeweils als
Binärbaum.
(10 Punkte)
Lösung:
Ausgangsfeld als virtueller Binärbaum:
37
79
28
33
11
36
90
21
99
37
79
99
33
11
36
90
28
7/20
21
37
99
79
33
36
11
90
21
28
fertiger Anfangsheap:
99
90
79
33
36
11
37
21
28
28 eingesunken:
90
79
33
36
11
37
28
21
99
8/20
28 eingesunken:
79
37
33
36
11
28
21
90
99
90
99
21 eingesunken:
37
33
21
36
11
28
79
11 eingesunken:
9/20
36
33
21
11
28
37
79
90
99
90
99
90
99
28 eingesunken:
33
28
11
21
36
37
79
21 eingesunken:
28
21
33
11
36
37
10/20
79
11 eingesunken:
21
11
28
33
36
37
79
90
99
fertig:
11
21
28
33
36
37
Lösung 4: AVL-Bäume
Gegeben sei folgender AVL-Baum:
11/20
79
90
99
18
12
9
24
15
19
13
28
22
a) Handelt es sich bei dem abgebildeten Baum um einen Heap?
25
(1 Punkt)
b) Fügen Sie nacheinander die Zahlen
• 17,
• 14 und
• 23
in diesen AVL-Baum ein und zeichnen Sie ihn nach jedem Einfügevorgang. Falls Rotationen zum Ausgleichen nötig sind, geben Sie bitte an, um welche es sich handelt!
(6 Punkte)
c) Löschen Sie aus dem obigen Ursprungsbaum (nicht dem erweiterten!) die Zahl 18.
(3 Punkte)
Lösung:
a) Nein, da bei einem Heap ein Knoten immer größer als seine Söhne sein muß, das ist
bei Suchbäumen im Allgemeinen nicht der Fall.
b)
12/20
Einfügen 17
18
12
24
9
15
13
19
17
28
22
25
Einfügen 14
18
12
24
9
15
13
19
17
28
22
25
14
R-Rotation um 15
18
12
24
9
13
19
15
14
22
17
13/20
28
25
L-Rotation um 12
18
13
12
9
24
15
19
17
14
28
22
25
Einfügen 23
18
13
12
9
24
15
19
17
14
28
22
25
23
L-Rotation um 19
18
24
13
12
9
15
14
22
17
14/20
19
28
23
25
c) Löschen der 18
15
15
13
Lösung 5: B-Bäume
Gegeben sei folgender B-Baum der Ordnung 2:
31 42 64
11 22
33 36 37 41
44 45 59
70 72 77 82
a) Fügen Sie nacheinander die Zahlen
• 27,
• 38 und
• 80
in diesen B-Baum ein und zeichnen Sie ihn nach jedem Einfügevorgang. Verwenden
Sie beim Einfügen den einfachen Algorithmus, d. h. bei einem Überlauf des Knotens
soll keine Anleihe beim Nachbarknoten gemacht werden.
(6 Punkte)
b) Löschen Sie aus Ihrem Ergebnis nacheinander die Schlüssel
• 36
• 64 und
• 11.
Zeichnen Sie dabei jeweils den B-Baum nach einem Löschvorgang.
Hinweis: Beim Löschen in einem Nicht-Blatt wird der Inorder-Vorgänger des zu löschenden Schlüssels (d. h. der nächstkleinere Schlüssel) an diese Stelle gebracht und
15/20
an der ursprünglichen Stelle gelöscht, so dass letztendlich im Blatt – wie in der Vorlesung angegeben – gelöscht werden kann. Sollten Anleihen bei einem Nachbarn oder
Verschmelzen mit einem Nachbarn nötig sein, soll zunächst der linke gewählt werden.
(6 Punkte)
c) Kann es sich beim oben abgebildeten Baum auch um einen B-Baum der Ordnung 3
handeln? Begründen Sie Ihre Antwort!
(1 Punkt)
Lösung:
a)
• Einfügen der 27:
31 42 64
11 22 27
33 36 37 41
44 45 59
70 72 77 82
• Einfügen der 38: (Überlauf)
31 37 42 64
11 22 27
33 36
38 41
44 45 59
70 72 77 82
• Einfügen der 80: (Doppelter Überlauf)
42
31 37
11 22 27
b)
33 36
64 77
38 41
• Löschen der 36: (Unterlauf und Anleihe links)
16/20
44 45 59
70 72
80 82
42
27 37
11 22
31 33
64 77
38 41
44 45 59
70 72
80 82
• Löschen der 64: (Ersetze 64 durch 59, lösche 59)
42
27 37
11 22
31 33
59 77
38 41
44 45
70 72
80 82
44 45
70 72
80 82
• Löschen der 11: (Doppelter Unterlauf)
37 42 59 77
22 27 31 33
38 41
c) Nein, da die B-Baum Bedingung nicht erfüllt ist: Bei Ordnung m müssen alle Knoten
außer der Wurzel mindestens m Werte, dürfen aber höchstens 2 · m Werte enthalten.
Das ist hier beim ersten Knoten der zweiten Reihe nicht der Fall.
[Die Kriterien, dass die Blätter auf einer Stufe liegen; alle Werte in den Knoten aufsteigend geordnet sind und dass die Nachfolgerzeiger auf Knoten zeigen, die (im Fall
des linken Nachfolgers) kleinere Werte beinhalten als der jeweilige Wert, von dem der
Zeiger ausgeht bzw. (im Fall des rechten Nachfolgers) größere Werte, sind alle erfüllt.
Aber das ist nicht gefragt, da das ja auch beim abgebildeten Baum gelten muß, hier
geht es um das m − 2 · m-Kriterium.]
17/20
Lösung 6: Hashverfahren
Gegeben sei die unten abgebildete Hashtabelle der Länge 11, bei der die Schlüssel mit der
Hashfunktion
h(k) = (2 ∗ k) MOD 11
bestimmt werden. Als Kollisionsstrategie wird interne Kollisionsbehandlung mit quadratischem Sondieren angewandt, d. h.
hi (k) = (h(k) + i2 ) MOD 11
0 1 2 3 4 5 6 7 8 9 10
12
30 19
16
a) Fügen Sie die folgenden Werte in der angegebenen Reihenfolge in diese Hashtabelle
ein und geben Sie dabei die Anzahl der aufgetretenen Kollisionen an:
• 65
• 14
• 41
(6 Punkte)
b) Was unternehmen Sie, wenn die Hashtabelle voll ist, Sie aber weitere Werte einfügen
müssen?
(2 Punkte)
Lösung:
a) h(65) = 2 ∗ 65 MOD 11 = 9 −→ ok
0 1 2 3 4 5 6 7 8 9 10
12
30 19
65 16
h(14) = 2 ∗ 14 MOD 11 = 6 −→ Kollision
h1 (14) = 6 + 12 MOD 11 = 7 −→ ok; 1 Kollision
18/20
0 1 2 3 4 5 6 7 8 9 10
12
30 19 14 65 16
h(41) = 2 ∗ 41 MOD 11 = 5 −→ Kollision
h1 (41) = 5 + 12 MOD 11 = 6 −→ Kollision
h2 (41) = 5 + 22 MOD 11 = 9 −→ Kollision
h3 (41) = 5 + 32 MOD 11 = 3 −→ ok; 3 Kollisionen
0 1 2 3 4 5 6 7 8 9 10
12 41 30 19 14 65 16
b) Die Hashtabelle muss in eine größere Hashtabelle umgeschrieben werden.
Lösung 7: Topologische Sortierung
a) Geben Sie eine topologische Sortierung für den folgenden gerichteten Graphen an:
-
1
2
6
?
-
4
3
(5 Punkte)
b) Betrachten Sie die Aussage:
Die topologische Sortierung eines gerichteten Graphen ohne Zyklen ist immer
eindeutig bestimmt.
Beweisen Sie die Aussage oder widerlegen Sie sie durch Angabe eines Gegenbeispiels.
(5 Punkte)
Lösung:
19/20
a) topologische Sortierung:
-
1 1
2 4
6
?
-
2 4
3 3
b) Gegenbeispiel:
-
1
?
?
-
4
2
3
hat zwei verschiedene topologische Sortierungen:
1 1
-
?
3 4
2 2
1 1
?
-
-
?
3 4
2 4
20/20
2 3
?
-
3 4
Herunterladen