• Keine Ergebnisse gefunden

1.4 Erklärung am Beispiel

N/A
N/A
Protected

Academic year: 2022

Aktie "1.4 Erklärung am Beispiel"

Copied!
9
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Wolfgang Hönig / Andreas Ecke WS 09/10

1 Quicksort

1.1 Aufgabentyp

Gegeben sei die Folge: [...]

Wenden Sie auf diese Folge den Quicksort-Algorithmus an und dokumentieren Sie den Rechenablauf wie folgt:

- Pivotelement jeweils kennzeichnen

- Stellung der Indizesi, j unmittelbar vor dem Tausch von Elementen - Stellung der Indizesi, j unmittelbar vor den rekursiven Aufrufen - Teilfolgen nach den rekursiven Aufrufen

1.2 Überblick

1. Pivotelementx=ahjlänge(a)−1

2

ki

;i= 0;j =länge(a)−1 2. Solangei≤j

a) Solangea[i]< x:i+ + b) Solangea[j]> x:j− −

c) Fallsi≤j: Vertausche a[i]und a[j];i+ +;j− − 3. quicksort(a[imin]. . . a[j]), falls mindestens zweielementig

quicksort(a[i]. . . a[jmax]), falls mindestens zweielementig

1.3 Grundidee

Große Elemente sollen schnell an das Ende und kleine Elemente schnell an den Anfang der Folge gebracht werden. Die (relative) Größe abzuschätzen ist allerdings recht schwierig.

Dafür gibt es das Pivotelement (x): Elemente die kleiner als dieses sind, können als „klein“

betrachtet werden, der Rest als „groß“. Quicksort teilt die Folge in zwei Hälften (das Pivot- element ist die Grenze) und sorgt mittels Tauschoperationen dafür, dass sich in der linken Hälfte die „kleinen“ Elementen befinden und in der rechten Hälfte die „großen“ Elemente.

Danach wird auf beiden Hälften rekursiv wieder der Quicksortalgorithmus aufgerufen. Die Effizienz hängt von der Wahl des Pivotelements ab, welches natürlich ein mittlerer Wert der Folge sein sollte. Der Algorithmus bei uns nimmt hierbei einfach an, dass dieser mitt- lere Wert auch bei dem mittleren Element zu finden ist (bzw. links von der Mitte, wenn die Anzahl der Elemente geradzahlig ist.)

1.4 Erklärung am Beispiel

Gegeben sei die Folge: 6,8,4,3,7

Quicksort arbeitet auf Feldern (also Arrays inC, im folgenden habe dieses den Namena).

Zu prokollieren ist der in der Aufgabe geforderte Rechenablauf. Dies wiederum bedeutet, dass der Algorithmus im Kopf nachvollzogen werden muss.

Im ersten Schritt wird das Pivotelementxbestimmt. Das Eingabefeldahat in diesem Bei- spiel 5 Elemente. Das mittlere Element ist offenbar das dritte Element oder inC-Notation

(2)

a[2]. Allgemein lässt sich die Indexposition auch wie im Überblick angegeben berechnen, allerdings ist es einfacher, wenn man sich merkt, dass es immer das mittlere Element (oder links davon) ist. Das Pivotelement wird durch eine Einrahmung gekennzeichnet. Zusätzlich werden zwei Indexzeigeriundj benötigt. Damit ergibt sich folgendes:

6 8 4 3 7

↑ ↑

i j

Große Elemente sollen schnell an das Ende wandern und kleine an den Anfang. Der Al- gorithmus sucht nun also links vom Pivotelement ein großes Element und rechts vom Pi- votelement ein kleines Element und vertauscht diese miteinander. Praktisch geschieht dies, durch die Fälle 2a bis 2c: der i-Zeiger wird solange erhöht (also nach rechts verschoben), bis ein passendes Element, welches größer oder gleich dem Pivotelement x ist gefunden wurde. Analoges geschieht fürj:

6 8 4 3 7

↑ ↑

i j

Offenbar ist 6 im Vergleich zu 4 schon groß (d.h. i wird nicht verändert). Aber 7 ist im Vergleich zu 4 nicht klein, also wirdj nach links verschoben (dekrementiert). Da die 3 im Vergleich zur 4 klein ist, kann der Tausch erfolgen (bei dem i und j auch entsprechend angepasst werden, um Doppelvertauschungen zu vermeiden):

3 8 4 6 7

↑ ↑ i j

8 ist relativ zur 4 ein großes Element. Die 4 ist relativ zur 4 ein kleines Element (man beachte, dass im Algorithmus a[i]< x bzw. a[j] > x steht, dass heißt 2a bzw. 2b enden spätestes beim Pivotelement). Damit erfolgt also wieder ein Tausch und es folgt:

3 4 8 6 7

↑ ↑

j i

Nun ist j < i, sodass 3. ins Spiel kommt. Da beide Teilfolgen mindestens zweielementig sind erfolgen zwei rekursive Aufrufe (d.h. auf beide Teilfolgen wird nochmal Quicksort angewendet.) Beide Teilfolgen werden bei uns gleichzeitig aufgeschrieben, auch wenn der Algorithmus (meistens) sequentiell abgearbeitet wird. Die Trennung der Teilfolgen erfolgt durch ein||. Da bei der ersten Teilfolge (3,4) keine echte Mitte haben, wird als Pivotelement das links von der Mitte gewählt, also 3:

3 4 8 6 7

↑ ↑ ↑ ↑

i j i j

Links: 4 ist relativ zu 3 groß, also wird j auf die 3 verschoben. Rechts: 8 ist schon relativ groß, also bleibt i bestehen. Die 7 ist allerdings auch relativ groß, also wird j auf die 6 verschoben:

(3)

Wolfgang Hönig / Andreas Ecke WS 09/10

3 4 6 8 7

↑ ↑ ↑ ↑

j i j i

Die Folge ist nun größtenteils sortiert, da nur noch eine Teilfolge (8,7) mindestens zweiele- mentig ist. Damit ergibt sich im dritten Durchlauf:

3, 4, 6, 8 7

↑ ↑

i j

3, 4, 6, 7 8

↑ ↑

j i

und als Ergebnis erhalten wir (wie zu erwarten war):

3, 4, 6, 7, 8

1.5 Anmerkungen

1.5.1 Eigenschaften

best case average case worst case stabil rekursiv O(nlogn) O(nlogn) O(n2) nein ja

(4)

2.1 Aufgabentyp

Wenden Sie auf die Folge: [...] den Shellsort-Algorithmus an. Wählen Sie hierbei für die Folge der Sortierabstände: [...]. Dokumentieren Sie jeweils:

- Abstandh und Anzahlanz der Teilfolgenglieder, - die Auswahl der zu sortierenden Teilfolge,

- die Wirkung der Funktion „Insertsort“ auf diese Teilfolge.

2.2 Überblick

1. Folgehn, hn−1, . . . ,1wählen (durch Aufgabe gegeben) 2. Für jedeshi:

a) anz=jlänge(a)

hi

k

b) für jedes 0≤k < hi

i. Teilfeld markieren:

a[k], a[k+hi], a[k+ 2hi], . . . , a[k+ (anz−1)hi] ii. InsertSort auf Teilfeld anwenden

2.3 Grundidee

Der vergleichsweise ineffiziente Algorithmus InsertSort (teilweise auch als Insertionsort be- zeichnet), soll optimiert werden. Die Grundidee hierbei ist, Teilfelder vorzusortieren sodass die komplette Sortierung des Gesamtfeldes dann letztendlich schneller abläuft.

2.4 Erklärung am Beispiel

Gegeben sei die Folge: 32, 6, 21, 5, 23, 11, 17, 8, 3, 12, 10 sowie die Sortierabstände 3,1 Der erste Sortierabstand ist laut Aufgabeh= 3. Die Folge hat 11 Elemente. Damit ergibt sich für die Anzahl der Elemente in der Teilfolge: anz=jlänge(a)

hi

k

=11

3

= 3

h= 3, anz = 3

Nun wird für jedes0≤k <3das Teilfeld markiert. Fürk= 0ergibt sich damit:a[0], a[0 + 3], a[0 + 6], oder grafisch:

32 6 21 5 23 11 17 8 3 12 10

(5)

Wolfgang Hönig / Andreas Ecke WS 09/10

Mitk= 1 folgt nun das nächste Teilfeld a[1], a[1 + 3], a[1 + 6]:

5 6 21 17 23 11 32 8 3 12 10

↑ ↑ ↑

Dieses Teilfeld wird wiederum mit Insertsort sortiert:

5 6 21 17 8 11 32 23 3 12 10

Mitk= 2 folgt nun das letzte Teilfeld a[2], a[2 + 3], a[2 + 6]:

5 6 21 17 8 11 32 23 3 12 10

↑ ↑ ↑

Was mit Insertsort sortiert ergibt:

5 6 3 17 8 11 32 23 21 12 10

Damit ist h = 3 abgeschlossen. Nun folgt der nächste Sortierabstand h = 1. Mit anz = jlänge(a)

hi

k

=11

1

= 11und k= 0 folgt:

h= 1, anz = 11

5 6 3 17 8 11 32 23 21 12 10

↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑

Ergebnis:

3, 5, 6, 8, 10, 11, 12, 17, 21, 23, 32

2.4.1 Klausurrelevante Schreibweise

h= 3, anz = 3

32 6 21 5 23 11 17 8 3 12 10

↑ ↑ ↑

5 6 21 17 23 11 32 8 3 12 10

↑ ↑ ↑

5 6 21 17 8 11 32 23 3 12 10

↑ ↑ ↑

h= 1, anz = 11

5 6 3 17 8 11 32 23 21 12 10

↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑

Ergebnis:

3, 5, 6, 8, 10, 11, 12, 17, 21, 23, 32

(6)

2.5 Anmerkungen

2.5.1 Eigenschaften

Algorithmus best case average case worst case stabil rekursiv

InsertSort O(n) O(n2) O(n2) ja nein

ShellSort O(nlogn) O(n1,2) O(n1,2) nein nein

Die Komplexität von Shellsort hängt sehr stark von der gewählten Folge der Sortierabstän- de ab. Die angegeben Komplexitäten gelten nur für eine (gut gewählte) Beispielfolge mit h(t+ 1) = 2h(t) + 1; andere Folgen können andere Komplexitäten erzielen, welche jedoch im average case immer schlechter alsnlognsein werden.

(7)

3 Heapsort

3.1 Aufgabentyp

Wenden Sie auf die Folge: [...] den Heapsort-Algorithmus an. Dokumentieren Sie in der Phase 1:

- das Einordnen in den binären Baum

- das schrittweise (knotenweise) Herstellen der Heap-Eigenschaft; hier insbesondere die Veränderungen durch die Funktion „sinkenlassen“.

und in der Phase 2:

- das Abspalten des jeweils letzten Elementes (Blattes) im Wechsel mit der - Wirkung der Funktion „sinkenlassen“.

3.2 Überblick

1. Herstellen heap-Eigenschaft (jeder Knoten muss größeren Wert haben als seine Nach- folger) (Phase 1)

a) Sinkenlassen eines jeden Knoten in einer Ebene / Schritt (von unten nach oben) 2. Sortieren (Phase 2)

a) Tausch von Wurzel- und letztem Element b) Abspaltung des letzten Elements

c) Sinkenlassen des Wurzelelements

3.3 Grundidee

Ein Array mit den zu sortierenden Daten kann leicht als Baum dargestellt werden, in dem alle Ebenen von links nach rechts und oben nach unten aufgefüllt werden. Der linke und rechte Nachfolger eines Knotens kann bei einem solchen Baum leicht über Indexoperatio- nen berechnet werden. Es genügt also einen solchen Baum zu betrachten, da durch die entsprechenden Indexoperationen die Sortierung dann auch auf Feldern funktioniert.

Bäume können außerdem die so genannte heap-Eigenschaft erfüllen. Das bedeutet, dass jeder Knoten einen größeren Wert als seine Nachfolgerknoten haben muss. Wenn der ge- samte Baum diese heap-Eigenschaft erfüllt, steht zwangsläufig an der Wurzel des Baumes das größte Element der Folge. Dieses kann mit dem letzten Element der Folge getauscht werden, damit nunmehr das größte Element am Ende der Folge steht. Für die restliche Fol- ge muss nun wiederum die heap-Eigenschaft hergestellt werden, damit ein erneuter Tausch beginnen kann.

3.4 sinkenlassen

Zur Herstellung der heap-Eigenschaft wird die Funktion sinkenlassen benutzt. Diese funk- tioniert auf einem kleinen Baum mittels eines einfachen Vergleichs:

1

(8)

Offenbar verletzt das Wurzelelement dieses Baumes die Heap-Eigenschaft. Außerdem ist 3 der größere der beiden Nachfolger, also werden 1 und 3 getauscht und es ergibt sich:

3 2 1

Größere Bäume können durch ebenenweises (von oben nach unten) Anwenden dieser Tausch- regel mit der heap-Eigenschaft versehen werden. Dafür muss gelten, dass bereits beide Teil- bäume die heap-Eigenschaft erfüllen (daher wird das sinkenlassen später auch von unten nach oben auf alle Knoten einmal angewendet). Nun kann die heap-Eigenschaft für den gesamten Baum hergestellt werden, indem solange mit dem jeweils größten Nachfolger ge- tauscht wird, bis es keinen Nachfolger mehr gibt, der größer als das aktuelle Element ist (trivial erfüllt, wenn das Element gar keinen Nachfolger hat).

1 5 4 2

7 3 6

−→

7 5 4 2

1 3 6

−→

7 5 4 2

6 3 1

3.5 Erklärung am Beispiel

Gegeben sei die Folge: 13, 6, 25, 4, 23, 11, 18, 9, 3, 19, 10, 7, 2

Zuerst wird aus der gegebenen Folge der Baum modelliert, indem die Ebenen des Baumes von links nach rechts und oben nach unten gefüllt werden. Somit müssten immer die obers- ten Ebenen vollständig gefüllt sein, lediglich die letzte Ebene kann ein teilweise Füllung aufweisen. Bei der Beispielfolge ergibt sich:

13

6 4 9 3

23 19 10

25 11 7 2

18

In Phase 1 muss die heap-Eigenschaft durch ebenenweises sinkenlassen hergestellt werden.

Im ersten Schritt wird hierzu die vorletzte Ebene betrachtet (Die letzte Ebene enthält kein Nachfolger mehr, sodass die heap-Eigenschaft trivial erfüllt ist). Dies sind also die Knoten mit der Beschriftung 18, 11, 23 und 4. Da der Knoten 18 ebenfalls keine Nachfolger mehr besitzt, muss sinkenlassen auf die anderen drei Knoten angewendet werden. Dies ist auch entsprechend mit s(Knotennummer) zu kennzeichnen (Auch wenn s(23) sowie s(11) keine direkte Wirkung zeigen, sollte doch gekennzeichnet werden, dass sinkenlassen aufgerufen wurde, da vorher noch nicht klar ist, dass der Teilbaum tatsächlich schon die heap-Eigenschaft erfüllt):

13

(9)

Wolfgang Hönig / Andreas Ecke WS 09/10

gelassen und im letzten Schritt der Knoten mit der Beschriftung 13:

s(25) s(6)−→

13

23 9 4 3

19 6 10

25 11 7 2

18

s(13)

−→

25

23 9 4 3

19 6 10

18 11 7 2

13

Offenbar erfüllt der Baum jetzt die heap-Eigenschaft.

In der Phase 2 wird der eigentliche Sortiervorgang ausgeführt, indem das Wurzelelement mit dem letzten Element getauscht und nach Abspaltung des (neuen) letzten Elementes wieder die heap-Eigenschaft des Restbaumes hergestellt wird.

In unserem Beispiel wird also zuerst die 2 mit der 25 getauscht. Danach wird die 25 abgespaltet, das heißt sie ist nicht mehr an der Sortierung beteiligt. Dies wird durch einen Rahmen gekennzeichnet. Für den Restbaum (also ohne die 25) wird wiederum die heap- Eigenschaft durch sinkenlassen der 2 hergestellt:

Tausch

−→

2

23 9 4 3

19 6 10

18 11 7 25

13

s(2)

−→

23

19 9 4 3

10 6 2

18 11 7 25

13

Dies geht im nächsten Schritt analog weiter: 7 und 23 werden getauscht, die 23 wird abgespaltet und die heap-Eigenschaft wird durch s(7) wieder hergestellt:

Tausch

−→

7

19 9 4 3

10 6 2

18 11

23 25

13

s(7)−→

19

10 9 4 3

7 6 2

18 11

23 25

13

Diese beiden Schritte genügend meistens in der Klausur (siehe Aufgabentext!). Eine voll- ständige Lösung kann in der Aufgabensammlung zur Lösung 6.13 (S. 195 ff.) nachgelesen werden.

3.6 Anmerkungen

3.6.1 Eigenschaften

best case average case worst case stabil rekursiv O(nlogn) O(nlogn) O(nlogn) nein nein

Referenzen

ÄHNLICHE DOKUMENTE

Alle V¨ ater sind kleiner als ihre

—° Alf6&#34;Wi nkei; weiche ‚zur Ableitung eines ändern erferderlich 5vateh und ' also zusäxi xmem gehören; sind.

Wege gehen - oben, unten, links und rechts Geraldine Kalberla, 2016.

Finde zu den fünf Teilen oben das fehlende Teil unterhalb der gestrichelten Linie und zeichne es oben ein... Angelika Rose Jeweils ein Teil von oben und ein Teil von unten

Karlsruher Institut f¨ ur Technologie Institut f¨ ur Theorie der Kondensierten Materie Ubungen zur Modernen Theoretischen Physik I ¨ SS

Nur wenn es auf allen Ebenen - der gesellwirtschaftlichen schaftlich-politischen, Konkurrenz, persönlichen, mitmenschliehen - gelingt, alle Erscheinungen von oben/unten, sobald

ben, das heißt mit anderen Worten, wenn die Arbeitsfiüssigkeit mit Be- 4 ginn der adiabatischen Expansion ungefähr 50% Wasser enthält, so wird ' auch während der Expansion

Stellt Udas Volumen der Mischung aus Dampf und Wasser in irgend einem Stadium des Kon- densationsprozesses bei der Temperatur T dar; sei ferner } jene Wärme, Welche 'abgegeben