10. Vorlesung (19.11.2013)

Werbung
Algorithmen und Datenstrukturen
Wintersemester 2013/14
10. Vorlesung
Algorithmen in Java
Krzysztof Fleszar
Lehrstuhl für Informatik I
1
Übersicht
• Berechnung der Potenz für zwei ganze Zahlen
• Klausuraufgabe SS 2010 !
• Berechnung der Cosinus-Funktion
• Klausuraufgabe WS 2010/2011 !
• Standard- und Referenzdatentypen
• Sortieren mit InsertionSort und MergeSort
• Anwendung: Zählen von falsch geordneten Paaren
• Anpassung der Algorithmen
2
Iterative Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
public class Potenz {
public static void main(String[] args) {
int x = 3;
int y = 4;
int potenz = 1;
for (int i = 0; i < y; i++) { //wird y-mal ausgefuehrt
potenz *= x;
}
System.out.println(x + " hoch " + y + " ist " + potenz);
}
}
3
Iterative Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
public class Potenz {
public static void main(String[] args) {
int x = 3;
int y = 4;
Besser:
Potenzberechnung
in eigener Methode
System.out.println(x + " hoch " + y + " ist " + potenz(x,y));
}
}
4
Iterative Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
public class Potenz {
public static void main(String[] args) {
int x = 3;
int y = 4;
System.out.println(x + " hoch " + y + " ist " + potenz(x,y));
}
public static int potenz(int x, int y) {
int potenz = 1;
for (int i = 0; i < y; i++) { //wird y-mal ausgefuehrt
potenz *= x;
}
return potenz;
}
}
5
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
public class Potenz {
public static void main(String[] args) {
int x = 3;
int y = 4;
System.out.println(x + " hoch " + y + " ist " + potenz(x,y));
}
public static int potenz(int x, int y) {
if (y == 0) return 1;
return x * potenz(x, y - 1);
}
}
An Basisfall denken!
๐‘ฆ
๐‘ฅ
=๐‘ฅ⋅
๐‘ฆ−1
๐‘ฅ
6
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
public class Potenz {
public static void main(String[] args) {
int x = 3;
int y = 4;
System.out.println(x + " hoch " + y + " ist " + potenz(x,y));
}
public static int potenz(int x, int y) {
if (y == 0) return 1;
return x * potenz(x, y - 1);
}
}
๐‘ฆ
๐‘ฅ
=๐‘ฅ⋅
Wie oft wird potenz aufgerufen?
๐‘ฆ−1
๐‘ฅ
๐‘ฆ + 1 -mal
7
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Geht es besser?
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ ⁄2
⋅๐‘ฅ
๐‘ฆ ⁄2
๐‘ฆ ⁄2
⋅๐‘ฅ
๐‘ฆ ⁄2
falls ๐‘ฆ gerade
⋅ ๐‘ฅ falls ๐‘ฆ ungerade
8
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Geht es besser?
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ ⁄2
๐‘ฆ ⁄2
⋅๐‘ฅ
⋅๐‘ฅ
๐‘ฆ ⁄2
๐‘ฆ ⁄2
falls ๐‘ฆ gerade
⋅ ๐‘ฅ falls ๐‘ฆ ungerade
public static int potenz(int x, int y) {
if (y == 0) return 1;
int p = potenz(x, y / 2) * potenz(x, y / 2);
if (y % 2 == 0) return p;
return p * x;
9
}
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Rekursionsgleichung (๐‘› = ๐‘ฆ):
๐‘‡ ๐‘› = 2๐‘‡ ๐‘›⁄2 + Θ 1
public static int potenz(int x, int y) {
if (y == 0) return 1;
int p = potenz(x, y / 2) * potenz(x, y / 2);
if (y % 2 == 0) return p;
return p * x;
10
}
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Rekursionsgleichung:
๐‘‡ ๐‘› = 2๐‘‡ ๐‘›⁄2 + Θ 1
๐‘Ž
๐‘
๐‘“ ๐‘›
๐‘“ ∈ ๐‘‚ ๐‘›1−๐œ€
log ๐‘ ๐‘Ž = log 2 2 = 1
z.B. für ๐œ€ = 0,5
Also gilt mit Fall 1 des Master-Theorems:
๐‘‡∈Θ ๐‘›
11
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Geht es besser?
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ ⁄2
๐‘ฆ ⁄2
⋅๐‘ฅ
⋅๐‘ฅ
๐‘ฆ ⁄2
๐‘ฆ ⁄2
falls ๐‘ฆ gerade
⋅ ๐‘ฅ falls ๐‘ฆ ungerade
public static int potenz(int x, int y) {
if (y == 0) return 1;
int p = potenz(x, y / 2) * potenz(x, y / 2);
if (y % 2 == 0) return p;
return p * x;
12
}
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Geht es besser?
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ
๐‘ฅ =๐‘ฅ
๐‘ฆ ⁄2
๐‘ฆ ⁄2
⋅๐‘ฅ
⋅๐‘ฅ
๐‘ฆ ⁄2
๐‘ฆ ⁄2
falls ๐‘ฆ gerade
⋅ ๐‘ฅ falls ๐‘ฆ ungerade
public static int potenz(int x, int y) {
if (y == 0) return 1;
int p = potenz(x, y / 2);
if (y % 2 == 0) return p * p;
return p * p * x;
}
13
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Rekursionsgleichung (๐‘› = ๐‘ฆ):
๐‘‡ ๐‘› = ๐‘‡ ๐‘›⁄2 + Θ 1
๐‘Ž
๐‘
๐‘“ ๐‘›
log ๐‘ ๐‘Ž = log 2 1 = 0
๐‘“∈Θ 1
Also gilt mit Fall 2 des Master-Theorems:
๐‘‡ ∈ Θ log ๐‘›
14
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Wie oft wird potenz aufgerufen?
๐‘ฆ wird in jedem Aufruf mindestens um
die Hälfte verringert.
Für ๐‘ฆ = 2๐‘˜ gibt es ๐‘˜ + 2 = log 2 ๐‘ฆ + 2 Aufrufe.
public static int potenz(int x, int y) {
if (y == 0) return 1;
int p = potenz(x, y / 2);
if (y % 2 == 0) return p * p;
return p * p * x;
}
15
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Wie oft wird potenz aufgerufen?
๐‘ฆ wird in jedem Aufruf mindestens um
die Hälfte verringert.
Es gibt
log 2 ๐‘ฆ + 2
Aufrufe!
public static int potenz(int x, int y) {
if (y == 0) return 1;
int p = potenz(x, y / 2);
if (y % 2 == 0) return p * p;
return p * p * x;
}
16
Rekursive Berechnung der Potenz
Berechnung der Potenz ๐‘ฅ ๐‘ฆ für zwei ganze Zahlen ๐‘ฅ und ๐‘ฆ.
Wie oft wird potenz aufgerufen?
๐‘ฆ wird in jedem Aufruf mindestens um
die Hälfte verringert.
Es gibt
Θ log ๐‘ฆ
Aufrufe!
public static int potenz(int x, int y) {
if (y == 0) return 1;
int p = potenz(x, y / 2);
if (y % 2 == 0) return p * p;
return p * p * x;
}
17
Übersicht
• Berechnung der Potenz für zwei ganze Zahlen
• Klausuraufgabe SS 2010 !
• Berechnung der Cosinus-Funktion
• Klausuraufgabe WS 2010/2011 !
• Standard- und Referenzdatentypen
• Sortieren mit InsertionSort und MergeSort
• Anwendung: Zählen von falsch geordneten Paaren
• Anpassung der Algorithmen
18
Berechnung der Cosinus-Funktion
cos 71.356° =
180°
360°
?
19
Berechnung der Cosinus-Funktion
1
cos ๐‘ฅ cos ๐‘ฆ = cos ๐‘ฅ − ๐‘ฆ + cos ๐‘ฅ + ๐‘ฆ
2
20
Berechnung der Cosinus-Funktion
1
cos ๐‘ฅ cos ๐‘ฆ = cos ๐‘ฅ − ๐‘ฆ + cos ๐‘ฅ + ๐‘ฆ
2
โŸบ cos ๐‘ฅ + ๐‘ฆ = 2cos ๐‘ฅ cos ๐‘ฆ − cos ๐‘ฅ − ๐‘ฆ
⇒ cos 2๐‘ฅ = 2cos 2 ๐‘ฅ −1
๐‘ฅ
2
⇒ cos ๐‘ฅ = 2cos −1
2
21
Berechnung der Cosinus-Funktion
๐‘ฅ
cos ๐‘ฅ = 2cos −1
2
2
public class Cosinus {
public static void main(String[] args) {
for (double i = 0; i <= 360; i += 15) {
System.out.println("cos " + i + " = "
+ cos(i * Math.PI / 180.0));
}
}
public static double cos(double x) {
return 2.0 * cos(x / 2.0) * cos(x / 2.0) - 1;
}
}
22
Berechnung der Cosinus-Funktion
๐‘ฅ
cos ๐‘ฅ = 2cos −1
2
2
public class Cosinus {
public static void main(String[] args) {
for (double i = 0; i <= 360; i += 15) {
System.out.println("cos " + i + " = "
+ cos(i * Math.PI / 180.0));
}
}
public static double cos(double x) {
double cosX2 = cos(x / 2.0);
return 2.0 * cosX2 * cosX2 - 1;
}
}
23
Berechnung der Cosinus-Funktion
๐‘ฅ
cos ๐‘ฅ = 2cos −1
2
2
Näherung für kleine Winkel (๐‘ฅ < 0.001): cos ๐‘ฅ = 1
public static double cos(double x) {
if (x < 0.001) return 1;
double cosX2 = cos(x / 2.0);
return 2.0 * cosX2 * cosX2 - 1;
}
180°
360°
24
Berechnung der Cosinus-Funktion
๐‘ฅ
cos ๐‘ฅ = 2cos −1
2
2
Ausgabe:
cos
cos
cos
cos
0.0 = 1.0
15.0 = 1.0
30.0 = 1.0
45.0 = 1.0
โ‹ฎ
cos 360.0 = 1.0
public static double cos(double x) {
if (x < 0.001) return 1;
double cosX2 = cos(x / 2.0);
return 2.0 * cosX2 * cosX2 - 1;
}
25
Berechnung der Cosinus-Funktion
๐‘ฅ
cos ๐‘ฅ = 2cos −1
2
2
Näherung für kleine Winkel (๐‘ฅ < 0.001):
1 2
cos ๐‘ฅ = 1 − ๐‘ฅ
2
public static double cos(double x) {
if (x < 0.001) return 1 – 0.5 * x * x;
double cosX2 = cos(x / 2.0);
return 2.0 * cosX2 * cosX2 - 1;
}
180°
360°
26
Berechnung der Cosinus-Funktion
๐‘ฅ
cos ๐‘ฅ = 2cos −1
2
2
Näherung für kleine Winkel (๐‘ฅ < 0.001):
1 2
cos ๐‘ฅ = 1 − ๐‘ฅ
2
1,5
1
0,5
0
0
50
100
150
200
250
300
350
400
-0,5
-1
-1,5
27
Berechnung der Cosinus-Funktion
๐‘ฅ
cos ๐‘ฅ = 2cos −1
2
Achtung: Verwende besser Methode cos
der Klasse java.lang.Math
2
28
Übersicht
• Berechnung der Potenz für zwei ganze Zahlen
• Klausuraufgabe SS 2010 !
• Berechnung der Cosinus-Funktion
• Klausuraufgabe WS 2010/2011 !
• Standard- und Referenzdatentypen
• Sortieren mit InsertionSort und MergeSort
• Anwendung: Zählen von falsch geordneten Paaren
• Anpassung der Algorithmen
29
Methoden mit Standarddatentypen
Inkrementieren einer Zahl a .
public class Zaehler {
public static void main(String[] args) {
int a = 1;
inkrementiere(a);
System.out.println("a = " + a);
}
public static void inkrementiere(int a) {
a++;
}
}
Ausgabe:
a = 1
30
Methoden mit Standarddatentypen
Inkrementieren einer Zahl a .
public class Zaehler {
public static void main(String[] args) {
int a = 1;
inkrementiere(a);
System.out.println("a = " + a);
}
public static void inkrementiere(int a) {
a++;
}
}
Bei Standarddatentypen wird Wert
von Variablen übergeben.
31
Methoden mit Standarddatentypen
Inkrementieren einer Zahl a .
public class Zaehler {
public static void main(String[] args) {
int a = 1;
a = inkrementiere(a);
System.out.println("a = " + a);
}
public static int inkrementiere(int a) {
return a + 1;
}
}
32
Methoden mit Referenzdatentypen
Inkrementieren der Zahlen in einem Feld.
public class FeldZaehler {
public static void main(String[] args) {
int[] A = {1, 3, 2, 4};
inkrementiere(A);
for (int i = 0; i < A.length; i++)
System.out.println("A" + i + " = " + A[i]);
}
public static void inkrementiere(int[] A) {
for (int i = 0; i < A.length; i++) A[i]++;
}
}
33
Methoden mit Referenzdatentypen
Inkrementieren der Zahlen in einem Feld.
public class FeldZaehler {
public static void main(String[] args) {
int[] A = {1, 3, 2, 4};
inkrementiere(A);
for (int i = 0; i < A.length; i++)
System.out.println("A" + i + " = " + A[i]);
}
public static void inkrementiere(int[] a) {
for (int i = 0; i < A.length; i++) a[i]++;
}
}
34
Ausgabe:
A0 = 2
A1 = 4
A2 = 3
A3 = 5
Methoden mit Referenzdatentypen
Inkrementieren der Zahlen in einem Feld.
public class FeldZaehler {
public static void main(String[] args) {
int[] A = {1, 3, 2, 4};
inkrementiere(A);
for (int i = 0; i < A.length; i++)
System.out.println("A" + i + " = " + A[i]);
}
public static void inkrementiere(int[] A) {
for (int i = 0; i < A.length; i++) A[i]++;
}
}
35
Bei Feldern wird Referenz übergeben.
Methoden mit Referenzdatentypen
Sortieren der Zahlen in einem Feld.
public class Sortierverfahren {
public static void main(String[] args) {
int[] A = {1, 3, 2, 4};
sort(A);
for (int i = 0; i < A.length; i++)
System.out.println("A" + i + " = " + A[i]);
}
public static void sort(int[] A) {
//TODO: Sortierverfahren Deines Vertrauens
}
}
36
Übersicht
• Berechnung der Potenz für zwei ganze Zahlen
• Klausuraufgabe SS 2010 !
• Berechnung der Cosinus-Funktion
• Klausuraufgabe WS 2010/2011 !
• Standard- und Referenzdatentypen
• Sortieren mit InsertionSort und MergeSort
• Anwendung: Zählen von falsch geordneten Paaren
• Anpassung der Algorithmen
37
Sortieren mit InsertionSort
public static void insertionSort(int[] A) {
for(int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i--;
InsertionSort(array of int ๐ด)
}
for ๐‘— = 2 to ๐ด.๐‘™๐‘™๐‘™๐‘™๐‘™๐‘™ do
A[i + 1] = key;
}
๐‘˜๐‘˜๐‘˜ = ๐ด ๐‘—
}
๐‘– =๐‘— −1
while ๐‘– > 0 and ๐ด ๐‘– > ๐‘˜๐‘˜๐‘˜ do
๐ด ๐‘–+1 =๐ด ๐‘–
๐‘– = ๐‘–−1
38
๐ด ๐‘– + 1 = ๐‘˜๐‘˜๐‘˜
Wohlstände und Fehlstände
Sei ๐ด = ๐‘Ž1 , ๐‘Ž2 , … , ๐‘Ž๐‘› eine Folge natürlicher Zahlen.
Wir nennen ein Indexpaar ๐‘–, ๐‘— mit 0 < ๐‘– < ๐‘— ≤ ๐‘›
• genau dann einen Wohlstand von ๐ด, wenn ๐‘Ž๐‘– < ๐‘Ž๐‘— .
• genau dann einen Fehlstand von ๐ด, wenn ๐‘Ž๐‘– > ๐‘Ž๐‘— .
Beispiel:
4,7,1,4,5,6
Wohlstand: 1,2
39
Wohlstände und Fehlstände
Sei ๐ด = ๐‘Ž1 , ๐‘Ž2 , … , ๐‘Ž๐‘› eine Folge natürlicher Zahlen.
Wir nennen ein Indexpaar ๐‘–, ๐‘— mit 0 < ๐‘– < ๐‘— ≤ ๐‘›
• genau dann einen Wohlstand von ๐ด, wenn ๐‘Ž๐‘– < ๐‘Ž๐‘— .
• genau dann einen Fehlstand von ๐ด, wenn ๐‘Ž๐‘– > ๐‘Ž๐‘— .
Beispiel:
4,7,1,4,5,6
Fehlstand: 1,3
40
Wohlstände und Fehlstände
Sei ๐ด = ๐‘Ž1 , ๐‘Ž2 , … , ๐‘Ž๐‘› eine Folge natürlicher Zahlen.
Wir nennen ein Indexpaar ๐‘–, ๐‘— mit 0 < ๐‘– < ๐‘— ≤ ๐‘›
• genau dann einen Wohlstand von ๐ด, wenn ๐‘Ž๐‘– < ๐‘Ž๐‘— .
• genau dann einen Fehlstand von ๐ด, wenn ๐‘Ž๐‘– > ๐‘Ž๐‘— .
Die Folge ๐‘›, ๐‘› − 1, … , 1 hat die meisten
Fehlstände aller Folgen mit ๐‘› Zahlen,
๐‘› ๐‘›−1
nämlich:
2
41
Wohlstände und Fehlstände
Sei ๐ด = ๐‘Ž1 , ๐‘Ž2 , … , ๐‘Ž๐‘› eine Folge natürlicher Zahlen.
Wir nennen ein Indexpaar ๐‘–, ๐‘— mit 0 < ๐‘– < ๐‘— ≤ ๐‘›
• genau dann einen Wohlstand von ๐ด, wenn ๐‘Ž๐‘– < ๐‘Ž๐‘— .
• genau dann einen Fehlstand von ๐ด, wenn ๐‘Ž๐‘– > ๐‘Ž๐‘— .
Anzahl Fehlstände + Anzahl Wohlstände =
(bei verschiedenen
๐‘› ๐‘›−1
Elementen in ๐ด)
2
42
Wohlstände und Fehlstände
Sei ๐ด = ๐‘Ž1 , ๐‘Ž2 , … , ๐‘Ž๐‘› eine Folge natürlicher Zahlen.
Wir nennen ein Indexpaar ๐‘–, ๐‘— mit 0 < ๐‘– < ๐‘— ≤ ๐‘›
• genau dann einen Wohlstand von ๐ด, wenn ๐‘Ž๐‘– < ๐‘Ž๐‘— .
• genau dann einen Fehlstand von ๐ด, wenn ๐‘Ž๐‘– > ๐‘Ž๐‘— .
Jeder Algorithmus zur Ausgabe aller Fehlstände in
๐‘จ braucht also im schlechtesten Fall alleine für die
Ausgabe
๐‘› ๐‘›−1
Operationen.
2
43
Wohlstände und Fehlstände
Sei ๐ด = ๐‘Ž1 , ๐‘Ž2 , … , ๐‘Ž๐‘› eine Folge natürlicher Zahlen.
Wir nennen ein Indexpaar ๐‘–, ๐‘— mit 0 < ๐‘– < ๐‘— ≤ ๐‘›
• genau dann einen Wohlstand von ๐ด, wenn ๐‘Ž๐‘– < ๐‘Ž๐‘— .
• genau dann einen Fehlstand von ๐ด, wenn ๐‘Ž๐‘– > ๐‘Ž๐‘— .
Idee: Fehlstände zählen, nicht ausgeben
44
Fehlstände zählen mit InsertionSort
public static void insertionSort(int[] A) {
for(int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i--;
}
A[i + 1] = key;
}
}
45
Fehlstände zählen mit InsertionSort
//sortiert a und gibt anzahl fehlstaende zurueck
public static int insertionSort(int[] A) {
int fehlstaende = 0;
for(int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i--;
fehlstaende++;
}
A[i + 1] = key;
}
return fehlstaende;
}
46
Fehlstände zählen mit InsertionSort
//sortiert a und gibt anzahl fehlstaende zurueck
public static int insertionSort(int[] A) {
int fehlstaende = 0;
for(int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
In Java
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i--;
fehlstaende++;
}
A[i + 1] = key;
}
return fehlstaende;
}
j = 4
1 2 5 7 3 6
Sortierter Bereich
47
Fehlstände zählen mit InsertionSort
//sortiert a und gibt anzahl fehlstaende zurueck
public static int insertionSort(int[] A) {
int fehlstaende = 0;
for(int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
Im Pseudocode!
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i--;
fehlstaende++;
}
A[i + 1] = key;
}
return fehlstaende;
}
๐‘— = 5
1 2 5 7 3 6
Sortierter Bereich
48
Fehlstände zählen mit InsertionSort
//sortiert a und gibt anzahl fehlstaende zurueck
public static int insertionSort(int[] A) {
int fehlstaende = 0;
for(int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
while (i >= 0 && A[i] > key) {
Behebt alle
A[i + 1] = A[i];
Fehlstände
i--;
fehlstaende++;
๐‘–, 5
}
A[i + 1] = key;
}
return fehlstaende;
}
1 2 5 7 3 6
Sortierter Bereich
49
Fehlstände zählen mit InsertionSort
//sortiert a und gibt anzahl fehlstaende zurueck
public static int insertionSort(int[] A) {
int fehlstaende = 0;
for(int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
while (i >= 0 && A[i] > key) {
Behebt alle
A[i + 1] = A[i];
Fehlstände
i--;
fehlstaende++;
๐‘–, 5
}
A[i + 1] = key;
}
return fehlstaende;
}
1 2 3 5 7 6
Sortierter Bereich
50
Fehlstände zählen mit InsertionSort
//sortiert a und gibt anzahl fehlstaende zurueck
public static int insertionSort(int[] A) {
int fehlstaende = 0;
Jeder
for(int j = 1; j < A.length; j++) {
Schleifenint key = A[j];
int i = j - 1;
durchlauf
while (i >= 0 && A[i] > key) {
behebt
A[i + 1] = A[i];
i--;
einen
fehlstaende++;
Fehlstand
}
A[i + 1] = key;
}
return fehlstaende;
}
1 2 3 5 7 6
Sortierter Bereich
51
Fehlstände zählen mit InsertionSort
Anzahl Fehlstände
≤ Anzahl Vergleiche bei InsertionSort
≤ Anzahl Fehlstände + ๐‘› − 1
52
Fehlstände zählen mit MergeSort
MergeSort(array of int ๐ด, int โ„“ = 1, int ๐‘Ÿ = ๐ด.๐‘™๐‘™๐‘™๐‘™๐‘™๐‘™)
if โ„“ < ๐‘Ÿ then
๐‘š = โ„“ + ๐‘Ÿ ⁄2
MergeSort(๐ด, โ„“, ๐‘š)
MergeSort(๐ด, ๐‘š + 1, ๐‘Ÿ)
Merge (๐ด, โ„“, ๐‘š, ๐‘Ÿ)
public static void mergeSort(int[] A, int l, int r) {
if (l < r) {
int m = (l + r) / 2;
mergeSort(A, l, m);
mergeSort(A, m + 1, r);
merge(A, l, m, r);
}
53
}
Fehlstände zählen mit MergeSort
MergeSort(array of int ๐ด, int โ„“ = 1, int ๐‘Ÿ = ๐ด.๐‘™๐‘™๐‘™๐‘™๐‘™๐‘™)
public static void mergeSort(int[] A) {
mergeSort(A, 0, A.length - 1);
}
public static void mergeSort(int[] A, int l, int r) {
if (l < r) {
int m = (l + r) / 2;
mergeSort(A, l, m);
mergeSort(A, m + 1, r);
merge(A, l, m, r);
}
54
}
Fehlstände zählen mit MergeSort
MergeSort(array of int ๐ด, int โ„“ = 1, int ๐‘Ÿ = ๐ด.๐‘™๐‘™๐‘™๐‘™๐‘™๐‘™)
public static void mergeSort(int[] A) {
mergeSort(A, 0, A.length - 1);
}
2x gleicher Methodenname erlaubt? Ja, solange Signatur verschieden!
public static void mergeSort(int[] A, int l, int r) {
if (l < r) {
int m = (l + r) / 2;
mergeSort(A, l, m);
mergeSort(A, m + 1, r);
merge(A, l, m, r);
}
55
}
Fehlstände zählen mit MergeSort
Merge(array of int ๐ด, int โ„“, int ๐‘š, int ๐‘Ÿ)
๐‘›1 = ๐‘š − โ„“ + 1
๐‘›2 = ๐‘Ÿ − ๐‘š
let ๐ฟ 1 … ๐‘›1 + 1 and ๐‘…[1 … ๐‘›2 + 1] be new arrays of int
๐ฟ 1 … ๐‘›1 = ๐ด[โ„“ … ๐‘š]
๐‘… 1 … ๐‘›2 = ๐ด[๐‘š + 1 … ๐‘Ÿ]
๐ฟ ๐‘›1 + 1 = ๐‘… ๐‘›2 + 1 = ∞
๐‘–=๐‘—=1
for ๐‘˜ = โ„“ to ๐‘Ÿ do
if ๐ฟ ๐‘– ≤ ๐‘… ๐‘— then
๐ด๐‘˜ =๐ฟ ๐‘–
๐‘–=๐‘– + 1
else
๐ด[๐‘˜] = ๐‘…[๐‘—]
๐‘— =๐‘—+1
1 4 7 2 3 6
๐‘š
๐‘Ÿ
โ„“
56
Fehlstände zählen mit MergeSort
Merge(array of int ๐ด, int โ„“, int ๐‘š, int ๐‘Ÿ)
๐‘›1 = ๐‘š − โ„“ + 1
๐‘›2 = ๐‘Ÿ − ๐‘š
let ๐ฟ 1 … ๐‘›1 + 1 and ๐‘…[1 … ๐‘›2 + 1] be new arrays of int
๐ฟ 1 … ๐‘›1 = ๐ด[โ„“ … ๐‘š]
๐‘… 1 … ๐‘›2 = ๐ด[๐‘š + 1 … ๐‘Ÿ]
๐ฟ ๐‘›1 + 1 = ๐‘… ๐‘›2 + 1 = ∞
๐‘–=๐‘—=1
for ๐‘˜ = โ„“ to ๐‘Ÿ do
if ๐ฟ ๐‘– ≤ ๐‘… ๐‘— then
๐ด๐‘˜ =๐ฟ ๐‘–
๐‘–=๐‘– + 1
else
๐ด[๐‘˜] = ๐‘…[๐‘—]
๐‘— =๐‘—+1
1 4 7 2 3 6
๐‘š
๐‘Ÿ
โ„“
1 4 7∞ 2 3 6∞
๐‘–
๐ฟ
๐‘—
๐‘…
57
Fehlstände zählen mit MergeSort
Merge(array of int ๐ด, int โ„“, int ๐‘š, int ๐‘Ÿ)
๐‘›1 = ๐‘š − โ„“ + 1
๐‘›2 = ๐‘Ÿ − ๐‘š
let ๐ฟ 1 … ๐‘›1 + 1 and ๐‘…[1 … ๐‘›2 + 1] be new arrays of int
๐ฟ 1 … ๐‘›1 = ๐ด[โ„“ … ๐‘š]
๐‘… 1 … ๐‘›2 = ๐ด[๐‘š + 1 … ๐‘Ÿ]
๐ฟ ๐‘›1 + 1 = ๐‘… ๐‘›2 + 1 = ∞
๐‘–=๐‘—=1
for ๐‘˜ = โ„“ to ๐‘Ÿ do
if ๐ฟ ๐‘– ≤ ๐‘… ๐‘— then
๐ด๐‘˜ =๐ฟ ๐‘–
๐‘–=๐‘– + 1
else
๐ด[๐‘˜] = ๐‘…[๐‘—]
๐‘— =๐‘—+1
1 4 7∞
๐‘–
2 3 6∞
๐‘—
58
Fehlstände zählen mit MergeSort
Merge(array of int ๐ด, int โ„“, int ๐‘š, int ๐‘Ÿ)
๐‘›1 = ๐‘š − โ„“ + 1
๐‘›2 = ๐‘Ÿ − ๐‘š
let ๐ฟ 1 … ๐‘›1 + 1 and ๐‘…[1 … ๐‘›2 + 1] be new arrays of int
๐ฟ 1 … ๐‘›1 = ๐ด[โ„“ … ๐‘š]
๐‘… 1 … ๐‘›2 = ๐ด[๐‘š + 1 … ๐‘Ÿ]
๐ฟ ๐‘›1 + 1 = ๐‘… ๐‘›2 + 1 = ∞
๐‘–=๐‘—=1
for ๐‘˜ = โ„“ to ๐‘Ÿ do
if ๐ฟ ๐‘– ≤ ๐‘… ๐‘— then
๐ด๐‘˜ =๐ฟ ๐‘–
๐‘–=๐‘– + 1
else
๐ด[๐‘˜] = ๐‘…[๐‘—]
๐‘— =๐‘—+1
1
1 4 7∞
๐‘–
2 3 6∞
๐‘—
59
Fehlstände zählen mit MergeSort
Merge(array of int ๐ด, int โ„“, int ๐‘š, int ๐‘Ÿ)
๐‘›1 = ๐‘š − โ„“ + 1
๐‘›2 = ๐‘Ÿ − ๐‘š
let ๐ฟ 1 … ๐‘›1 + 1 and ๐‘…[1 … ๐‘›2 + 1] be new arrays of int
๐ฟ 1 … ๐‘›1 = ๐ด[โ„“ … ๐‘š]
๐‘… 1 … ๐‘›2 = ๐ด[๐‘š + 1 … ๐‘Ÿ]
๐ฟ ๐‘›1 + 1 = ๐‘… ๐‘›2 + 1 = ∞
๐‘–=๐‘—=1
for ๐‘˜ = โ„“ to ๐‘Ÿ do
if ๐ฟ ๐‘– ≤ ๐‘… ๐‘— then
๐ด๐‘˜ =๐ฟ ๐‘–
๐‘–=๐‘– + 1
else
๐ด[๐‘˜] = ๐‘…[๐‘—]
๐‘— =๐‘—+1
1 2
1 4 7∞
๐‘–
2 3 6∞
๐‘—
60
Fehlstände zählen mit MergeSort
Merge(array of int ๐ด, int โ„“, int ๐‘š, int ๐‘Ÿ)
๐‘›1 = ๐‘š − โ„“ + 1
๐‘›2 = ๐‘Ÿ − ๐‘š
let ๐ฟ 1 … ๐‘›1 + 1 and ๐‘…[1 … ๐‘›2 + 1] be new arrays of int
๐ฟ 1 … ๐‘›1 = ๐ด[โ„“ … ๐‘š]
๐‘… 1 … ๐‘›2 = ๐ด[๐‘š + 1 … ๐‘Ÿ]
๐ฟ ๐‘›1 + 1 = ๐‘… ๐‘›2 + 1 = ∞
๐‘–=๐‘—=1
for ๐‘˜ = โ„“ to ๐‘Ÿ do
if ๐ฟ ๐‘– ≤ ๐‘… ๐‘— then
๐ด๐‘˜ =๐ฟ ๐‘–
๐‘–=๐‘– + 1
else
๐ด[๐‘˜] = ๐‘…[๐‘—] Wird von Feld ๐‘… gewählt, so werden
๐‘— =๐‘—+1
๐‘› – ๐‘– + 1 Fehlstände beseitigt. 61
1 2
1 4 7∞
1
๐‘–
2 3 6∞
๐‘—
Fehlstände zählen mit MergeSort
๐‘“=0
for ๐‘˜ = โ„“ to ๐‘Ÿ do
if ๐ฟ ๐‘– ≤ ๐‘… ๐‘— then
๐ด๐‘˜ =๐ฟ ๐‘–
๐‘–=๐‘– + 1
else
๐ด[๐‘˜] = ๐‘…[๐‘—]
๐‘“ = ๐‘“ + ๐‘›1 − ๐‘– + 1
๐‘— =๐‘—+1
return ๐‘“
Fehlstände
lassen sich mit
MergeSort zählen!
Wird von Feld ๐‘… gewählt, so werden
๐‘›1– ๐‘– + 1 Fehlstände beseitigt.
62
Fehlstände zählen mit MergeSort
public static int mergeSort(int[] A, int l, int r) {
int fehlstaende = 0;
if (l < r) {
int m = (l + r) / 2;
fehlstaende += mergeSort(A, l, m);
fehlstaende += mergeSort(A, m + 1, r);
fehlstaende += merge(A, l, m, r);
}
return fehlstaende;
}
63
Schluss
Bei Rekursionen
• denkt an den Basisfall/Rekursionsabbruch!
• vermeidet Mehrfachaufrufe mit gleichem Argument
• leitet die Rekursionsgleichungen her!
Aufgabe Wohlstände/Fehlstände
• passt bekannte Algorithmen an
• Ausgabe aller Fehlstände
≠ Ausgabe Anzahl Fehlstände
64
Herunterladen