Prof. Dr. A. Poetzsch-Heffter Dipl.-Inform. J. O. Blech Dipl.-Inform. M. J. Gawkowski Dipl.-Inform. N. Rauch
TU Kaiserslautern
Fachbereich Informatik AG Softwaretechnik
L¨ osungvorschlag zum ¨ Ubungsblatt 9: Software-Entwicklung I (WS 2006/07)
Aufgabe 1 Zeitaufwand
a) Beh.: Es gibt c,din Nat so dass f¨ur alle N in Nat gilt:
g(N)≤c∗N2+d
Bew.: W¨ahle c= 2, d= 10000. Zeige die Behauptung mit vollst¨andiger Induktion.
Ind.-Anfang: N = 0: g(0) = 0 + 02 + 10000≤2∗02+ 10000 Ind.-Schritt: N →N + 1 f¨ur N ≥1:
g(N+1) = (N+1)+N+12 +10000 =N+N2 +1+12+10000≤Ind.−Vorr.2∗N2+1+12+10000≤N≥1 2N2+ 4N+ 2 + 10000 = 2∗(N2+ 2N+ 1) + 10000 = 2∗(N+ 1)2+ 10000
b)
O(1) O(logn) O(n) O(nlogn) O(n2) O(2n)
f(n) nein nein ja ja ja ja
g(n) nein nein ja ja ja ja
h(n) nein nein nein nein ja ja
i(n) nein nein nein nein nein nein j(n, m) nein nein nein nein nein nein
k(n) ja ja ja ja ja ja
c) Beweis der Enthaltenseinsbeziehungen:
• Beh.: O(2)⊆O(n) Bew.:
O(2)⊆O(n)
⇐⇒ {g | ∃c, d ∈ N at :∀N ∈ N at : g(N) ≤ c∗2 +d} ⊆ {g | ∃s, t ∈ N at : ∀N ∈ N at : g(N)≤s∗N +t}
⇐⇒ ∃c, d, s, t∈N at:∀N, g∈N at:g(N)≤c∗2 +d⇒g(N)≤s∗N +t
Es gelteg(N)≤c∗2 +d. W¨ahle s=c,t= 2c+d. Zu zeigen: g(N)≤c∗N + 2c+d Bew.: Sei N = 0. Es gilt g(0)≤c∗2 +d= 2c+d=c∗0 + 2c+d.
Sei N >0. Es giltg(N)≤c∗2 +d≤c∗N+ 2c+d.
• Beh.: O(nlogn)⊆O(n3) Bew.: O(nlogn)⊆O(n3)
⇐⇒ {g | ∃c, d ∈ N at : ∀N ∈ N at : g(N) ≤ c∗NlogN +d} ⊆ {g | ∃s, t ∈ N at :∀N ∈ N at:g(N)≤s∗N3+t}
⇐⇒ ∃c, d, s, t∈N at:∀N, g∈N at:g(N)≤c∗NlogN+d⇒g(N)≤s∗N3+t Es gelteg(N)≤c∗NlogN +d. W¨ahle s=c,t=d. Zu zeigen: g(N)≤c∗N3+d Bew.: SeiN >0. Es giltg(N)≤c∗NlogN+d≤c∗N∗N∗N+d=c∗N3+d, da f¨ur N >0 gilt logN ≤N.
d) Prinzipiell l¨asst sich die Anzahl der Methodenaufrufe durch Summation der (verschachtelten) Schleifendurchl¨aufe und Einsatz der entsprechenden Summenformeln ermitteln.
1.
C(n) =
n+1
X
i=1 2n
X
j=i
2
= 2(
1
X
i=1 2n
X
j=i
1 +
n+1
X
i=2 2n
X
j=i
1)
= 2(
2n
X
j=1
1 +
n+1
X
i=2
2n
X
j=1
1−
i−1
X
j=1
1
)
= 2(2n+
n+1
X
i=2
(2n)−
n+1
X
i=2
(i−1))
= 2(2n(n+ 1)−
n
X
i=1
i)
= 2(2n(n+ 1)−n(n+ 1)
2 )
= 2(3 2n2+3
2n)
= 3n2+ 3n) C(n) ∈ O(n2)
2. Bei dieser Aufgabe wird die ¨außerste Schleife nur einmal durchlaufen, da der Indexiin der mittleren Schleife mit hochgez¨ahlt wird. Es gilt also stetsj=i. Daher bleibt die ¨außerste Schleife bei der Summation unber¨ucksichtigt.
C(n) =
n
X
j=1
(
j
X
k=1
1 + 1)
=
n
X
j=1
(j+ 1)
= n(n+ 1)
2 +n
= 1 2n2+3
2n C(n) ∈ O(n2)
Aufgabe 2 Zweidimensionale Sucheb¨ aume (praktisch)
class Dim2Tree { int xcoord;
int ycoord;
Dim2Tree xless, xgreater;
Dim2Tree yless, ygreater;
}
public class uebung09a2 extends InputOutput {
static boolean contains( Dim2Tree b, int xcoord, int ycoord ) { if (b == null) return false;
if (b.xcoord == xcoord && b.ycoord == ycoord) return true;
if (xcoord < b.xcoord) return (contains (b.xless,xcoord,ycoord));
if (xcoord > b.xcoord) return (contains (b.xgreater,xcoord,ycoord));
if (ycoord < b.ycoord) return (contains (b.yless,xcoord,ycoord));
if (ycoord > b.ycoord) return (contains (b.ygreater,xcoord,ycoord));
return false; //sollte nicht erreicht werden }
static void printTree( Dim2Tree b ) { if (b != null) {
println ("X-Koordinate:"+b.xcoord+", Y-Koordinate:"+ b.ycoord );
printTree (b.yless);
printTree (b.ygreater);
printTree (b.xless);
printTree (b.xgreater);
}
return;
}
static void sortedInsert( Dim2Tree b, int xcoord, int ycoord ) { if (b == null) return;
if (b.xcoord == xcoord && b.ycoord == ycoord) return;
if( xcoord < b.xcoord ) { if( b.xless == null ) {
b.xless = mkBinTree(xcoord,ycoord); return;
} else {
sortedInsert(b.xless,xcoord,ycoord);return;
}
} else if( b.xcoord < xcoord ) { if( b.xgreater == null ) {
b.xgreater = mkBinTree(xcoord,ycoord); return;
} else {
sortedInsert(b.xgreater,xcoord,ycoord);return;
} }
if( ycoord < b.ycoord ) { if( b.yless == null ) {
b.yless = mkBinTree(xcoord,ycoord); return;
} else {
sortedInsert(b.yless,xcoord,ycoord);return;
}
} else if( b.ycoord < ycoord ) { if( b.ygreater == null ) {
b.ygreater = mkBinTree(xcoord,ycoord); return;
} else {
sortedInsert(b.ygreater,xcoord,ycoord);return;
} }
}
static Dim2Tree mkBinTree( int xcoord,int ycoord ) { Dim2Tree t;
t = new Dim2Tree();
t.xcoord = xcoord;
t.ycoord = ycoord;
return t;
}
public static void main (String []args) { Dim2Tree b = mkBinTree (10,10);
sortedInsert (b,100,100);
sortedInsert (b,50,42);
sortedInsert (b,50,45);
sortedInsert (b,60,42);
printTree(b);
} }
Aufgabe 3 Mergesort vs. Quicksort
Mergesort hat einen Aufwand inO(n log n), Quicksort inO(n2) (n ist die L¨ange des zu sortierenden Feldes). In der Praxis ist Quicksort meistens schneller als Mergesort, da der Worst-Case (sehr kleines oder großes Pivot Element) selten eintritt und keine Arrays kopiert werden m¨ussen. Bei den Beispielimplementierungen liegt der Unterschied im Normalfall bei ca. einem Drittel zugunsten von Quicksort.
public class uebung09a3Mergesort extends InputOutput { static final int maxIndex=20000000;
static int[] array = new int[maxIndex+1];
static int[] tarray = new int[maxIndex+1];
static void fill() {
for (int i=0; i<=maxIndex; i++) {
array[i] = (987654321 % (12345 + i)) % 100 ; } }
static void mergesort(int l, int r) { int nl = r;
int nr = l;
int m;
if (r > l) { m = (l + r)/2;
mergesort(l, m);
mergesort(m+1, r);
for (int k=l; k<=m; k++)
for (int k=m+1; k<=r; k++)
tarray[r + m - k + 1] = array[k];
for (int k=l; k<=r; k++) {
if (tarray[nr] < tarray[nl]) { array[k] = array[nr];
nr++;
} else {
array[k] = tarray[nl];
nl--;
} }
} }
public static void main(String[] args) { fill();
mergesort(0, maxIndex);
} }
public class loesung09a3Quicksort extends InputOutput { static int[] array;
static final int maxIndex=20000000;
static void fill() {
for (int i=0; i<=maxIndex; i++) {
array[i] = (987654321 % (12345 + i)) % 100 ; } }
static void swap (int a, int b) { int t = array[a];
array[a] = array[b];
array[b] = t;
}
static void quicksort(int l, int r) { int nl = r;
int nr = l;
int pivot;
if (nr < nl) {
pivot = array[(nr + nl)/2];
while (nr <= nl) {
while ((nr < r) && (array[nr] < pivot)) nr++;
while ((nl > l) && (array[nl] > pivot)) nl--;
if (nr <= nl) { swap(nr, nl);
nr++;
nl--;
}
}
if (nl > l) quicksort (l, nl);
if (nr < r) quicksort (nr, r);
} }
public static void main(String[] arg) { array = new int[maxIndex+1];
fill();
quicksort(0, maxIndex);
} }