• Keine Ergebnisse gefunden

Übung Algorithmen und Datenstrukturen 10. Übung: Zusatzaufgaben

N/A
N/A
Protected

Academic year: 2022

Aktie "Übung Algorithmen und Datenstrukturen 10. Übung: Zusatzaufgaben"

Copied!
4
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Wolfgang Hönig / Andreas Ecke WS 09/10

Übung Algorithmen und Datenstrukturen

10. Übung: Zusatzaufgaben

1. a) Geben Sie eine rekursive Funktion für die Fakultätsfunktion (n!) an.

b) Neben der Zeitkomplexität, spielt auch die Platzkomplexität eine große Rolle.

Untersuchen Sie Ihre Funktion aus a) im best-, average- und worstcase darauf.

c) Vergleichen Sie die Ergebnisse mit einer iterativen Lösung für n!.

2. Schreiben Sie in C eine Funktion List_to_Tree, die aus einer Liste mit Integer- schlüsselwerten einen Binärbaum erzeugt.

a) Die Art des Baumes ist egal, d.h. die Funktion soll möglichst einfach gehalten sein

b) Der Baum soll von links nach rechts aufgebaut werden, d.h. beinEbenen sollen n−1Ebenen komplett gefüllt sein und dien−te Ebene nur ganz links aufgefüllt sein (siehe auch Heapsort-bäume).

3. Gegeben sie die Folge: Anton1 ,Bernd4 ,Karl1 ,Otto4 ,Paul4 , welche früher nach Namen sortiert wurde. (Die Folge ist ein Zusammengesetzter Datentyp bestehend aus Name und Zahl.). Sortieren Sie die Folge mit Hilfe von Quicksort nach Zahlen. Was fällt am Ergebnis auf? Vergleichen Sie das Ergebnis mit dem, welches Sie erhalten, wenn Sie Bubblesort auf die Folge anwenden.

Wie können Sie erreichen, dass Quicksort das selbe Ergebnis liefert?

Lösungen

1. a) rekursiv:

1 i n t f a k (i n t n ) 2 {

3 i f ( n == 0 ) /∗A∗/

4 return 1 ;

5

6 return n ∗ f a k ( n − 1 ) ; /∗B∗/

7 }

b) Best-, average- und worstcase fallen bei dieser Funktion zusammen, da es keine

„zufällige“ Größe wie bei einem Sortieralgorithmus gibt.

Für den Zeitbedarf ergibt sich: (A+B)·n+A mit A = 1E (Vergleich) und B = 3E (Subtraktion, Funktionsaufruf, Multiplikation) ergibt sich:4n+ 1, also in LandaunotationO(n).

Für den Platzbedarf ergibt sich:(n+ 1) (für den Funktionsparameter n), also in LandaunotationO(n).

c) iterative Lösung:

1 i n t f a k (i n t n ) 2 {

3 i n t p = 1 ; /∗A∗/

4 while ( n >= 1 ) {/∗B∗/

5 p = p ∗ n ;/∗C∗/

6 n = n − 1 ;/∗D∗/

(2)

7 } 8

9 return p

10 }

Zeitbedarf: A + (n + 1) ·B +n ·(C +D) ergibt mit A = 1E (Zuweisung), B = 1E (Vergleich), C =D= 2E (mathematische Operation und Zuweisung):

1 + (n+ 1) + 4n, also O(n).

Platzbedarf: 2(Variablen p und n), also O(1).

Insgesamt ist die iterative Lösung wegen des geringeren Platzbedarfs also vor- zuziehen. Die exakten Konstanten sind i.d.R. irrelevant, da eine andere Rech- nerarchitektur oder die Implementierung direkt in Assembler viel ändern kann.

2. a) Eine Liste ist ein Sonderfall des Baumes, mit t->leftoder t->right=NULL.

Somit ergibt sich:

1 void List_to_Tree1 ( LPtr l , TPtr ∗t ) 2 {

3 i f( l==NULL)

4 {

5 ∗t = NULL ;

6 return;

7 }

8 ∗t = ( TPtr ) m a l l o c (s i z e o f( btype ) ) ; 9 (∗t)−>key = l−>key ;

10 List_to_Tree1 ( l−>next , & ( (∗t)−> l e f t ) ) ; 11 (∗t)−> r i g h t = NULL ;

12 }

b) Heapsort arbeitet natürlich auf Arrays und nicht auf Listen. Trotzdem ist der linke Nachfolger des n−ten Elementes über 2n+ 1 und der rechte Nachfolger den n−ten Elementes über 2n+ 2 erreichbar. Diese Idee wird in der folgenden Funktion auf Listen realisiert:

1 void List_to_Tree ( LPtr l , TPtr ∗t , i n t pos ) 2 {

3 i n t i ;

4 i f( l==NULL)

5 {

6 ∗t = NULL ;

7 return;

8 }

9

10 ∗t = ( TPtr ) m a l l o c (s i z e o f( btype ) ) ; 11 (∗t)−>key = l−>key ;

12 (∗t)−> r i g h t = NULL ;

13 // l e f t w i r d r e k u r s i v NULL g e s e t z t 14

15 f o r( i =0; i <2∗pos+1−pos && l ; i ++)

16 l = l−>n e x t ;

17 List_to_Tree ( l , & ( (∗t)−> l e f t ) , 2∗pos + 1 ) ; 18 i f( l != NULL)

19 List_to_Tree ( l−>next , & ( (∗t)−> r i g h t ) , 2∗pos + 2 ) ; 20 }

(3)

3. Anton1 Bernd4 Karl1 Otto4 Paul4

i j

1 Anton

4 Bernd

1 Karl

4 Otto

4 Paul

i j

1 Karl

4 Bernd

1 Anton

4 Otto

4 Paul

i, j

1 Karl

4 Bernd

1 Anton

4 Otto

4 Paul

j i

1 Karl

4 Bernd

1 Anton

4 Otto

4 Paul

i j

1 Karl

4 Bernd

1 Anton

4 Otto

4 Paul

i j

1 Karl

1 Anton

4 Bernd

4 Otto

4 Paul

j i

1 Karl

1 Anton

4 Bernd

4 Otto

4 Paul

i j

1 Karl

1 Anton

4 Paul

4 Otto

4 Bernd

i, j

1 Karl

1 Anton

4 Paul

4 Otto

4 Bernd

j i

Ergebnis: Karl1 ,Anton1 ,Paul4 ,Otto4 ,Bernd4

Bewertung: Offenbar ist die Folge jetzt zwar nach Zahlen sortiert, allerdings ohne dabei auf die vorher schon erhaltene alphabetische Sortierung zu achten. Quicksort ist ein so genannter instabiler Algorithmus, d.h die Reihenfolge der Datensätze mit gleichem Sortierschlüssel wird nicht bewahrt.

Bubblesort hingegen ist ein stabiler Algorithmus, d.h. die Reihenfolge von Elementen mit dem gleichen Schlüssel bleibt erhalten, und man erhält das Ergebnis: Anton1 , Karl1 ,

4

Bernd, Otto4 , Paul4 . Wählt man sich zum Beispiel alle Elemente mit der Nummer 4, so erhält man: Bernd, Otto und Paul und erkennt, das diese immer noch alphabetisch sortiert sind.

Wie kann man nun Quicksort so modifizieren, das es die selbe Folge liefert? Dies geht, in dem man die Vergleichsfunktion so verändert, dass nicht einfach nur die Zahlen verglichen werden, sondern auch noch die Namen (wenn die Zahlen gleich sind). Sei zum Beispiel jedes Element vom Typ:

1 s t ru c t e l e m e n t {

2 i n t z a h l ;

3 char name [ 2 0 ] ; 4 } ;

Eine Vergleichsfunktion, die die Sortierung der Namen erhält, würde dann so ausse- hen (wobei die Funktionstrcmp 2 Zeichenketten miteinander vergleicht und je nach Ergebnis -1, 0 oder 1 zurückgibt):

1 i n t compare (s t ru c t e l e m e n t a1 , s t ru c t e l e m e n t a2 ) { 2 i f ( a1 . z a h l <a2 . z a h l ) return −1;

3 e l s e i f ( a1 . z a h l >a2 . z a h l ) return 1 ; 4 e l s e return strcmp ( a1 . name , a2 . name ) ;

(4)

5 }

Die Verwendung einer Vergleichsfunktion bei Quicksort ist in C z.B. mit qsort möglich.

Referenzen

ÄHNLICHE DOKUMENTE

Wolfgang Hönig WS 09/101. Übung Algorithmen

• Suchbaum: Für jeden Knoten gilt: alle Schlüssel im linken Teilbaum sind kleiner und alle Schlüssel im rechten Teil- baum sind größer als der Schlüssel des Knotens. •

Dies liegt an einem kleinen, aber gern gemachten Tippfehler: Die while-Schleife führt die erste Anweisung oder den ersten Block solange aus, bis die Bedingung nicht mehr erfüllt

Geben Sie eine BNF-Definition B an, die folgende Sprache beschreibt (siehe auch Zusatzaufgaben der 33. Ist die Grammatik (bzw. BNF-Definition)

Durch die schrittweise Abarbeitung ist es allerdings auch nicht möglich nach endlich vielen Schritten eine unendliche Sprache eindeutig zu definie- ren (Falls man eine Vermutung

Durch den Durchschnitt zweier Sprachen, welche durch EBNF-Definitionen beschrie- ben werden, kann eine neue Sprache entstehen, welche sich nicht mit einer einzelnen

minimale Beispiele der Wörter aufschreiben2. aktuelles Wort und

Hinweis: Wenn die Übung immer noch zu langweilig ist, lohnt es sich alle Syntaxdia- grammsysteme der obigen Aufgaben in die entsprechende EBNF