• Keine Ergebnisse gefunden

SUCHEN  UND  SORTIEREN

N/A
N/A
Protected

Academic year: 2021

Aktie "SUCHEN  UND  SORTIEREN"

Copied!
90
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Algorithmen  &  Datenstrukturen   Prof.  Dr.  Wolfgang  Schramm  

SUCHEN  UND  SORTIEREN  

Kapitel  5    

(2)

1  

Übersicht  

1.  Einführung   2.   Algorithmen  

3.  EigenschaDen  von  

Programmiersprachen   4.   Algorithmenparadigmen   5.   Suchen  &  SorLeren  

6.   Hashing  

7.   Komplexität  von  Algorithmen   8.   Abstrakte  Datentypen  (ADT)   9.   Listen  

10.  Bäume  

11.  Graphen  

(3)

2  

Lernziele  des  Kapitels  

¨ 

Kennenlernen  von   Suchstrategien?  

¨ 

Verstehen  warum  man  vor  der   Suche  besser  sorLert.  

¨ 

Kennenlernen  verschiedener   SorLeralgorithmen  und  ihrer   speziellen  EigenschaDen.  

¨ 

Verstehen,  warum  verschiedene   SorLeralgorithmen  entwickelt   wurden.  

¨ 

Vergleich  und  Bewertung  der   verschiedenen  

SorLeralgorithmen.  

2

(4)

3  

Inhalt  

o 

Suchalgorithmen  

o 

Aufwand  für  das  Suchen  

o 

Grundlegende  SorLeralgorithmen  

o 

EigenschaDen  von  SorLeralgorithmen  

o 

Ein  paar  besondere  SorLeralgorithmen  

o 

Vergleich  der  SorLeralgorithmen  

o 

Laufzeitverhalten  der  SorLeralgorithmen  

o 

Die  Algorithmen  werden  in  Pseudocode  und  in  Java  bzw.  in  Mischformen  

angegeben.  

(5)

4  

Suchen  –  in  sorLerten  Folgen  

o 

Voraussetzung:  Arrays  in  Java  sind  bekannt.  

o 

Eine  der  häufigsten  Aufgaben  in  der  InformaLk:  Suchen  von  Daten.  

o 

Der  einfachste  Fall:  Suchen  in  sorLerten  Folgen.  

o 

Vereinfachende  Annahmen:  

¤ 

Folge  =  Feld  von  numerischen  Werten.  

¤ 

Auf  jedes  Element  der  Folge  F  kann  über  den  Index  i  zugegriffen   werden  (mit  F[i]).  Erstes  Element:  F[1],  letztes  Element  bei  n   Werten:  F[n].  

¤ 

Für  die  Feldelemente  sind  die  bekannten  Vergleichsoperatoren  =,  <  

und  >  definiert.  

¤ 

Der  für  die  Suche  relevante  Teil  ist  der  numerische  Wert,  nach  dem  

gesucht  wird.  Der  gesuchte  Wert  ist  der  Suchschlüssel.  

(6)

5  

Sequenzielle  Suche  

o 

Die  Folge  wird  sequenziell  durchlaufen,  beginnend  beim  ersten  Element.  

o 

In  jedem  Schrin  wird  das  aktuelle  Element  mit  dem  Suchschlüssel  verglichen.  

o 

Sobald  das  gesuchte  Element  gefunden  wurde,  kann  die  Suche  beendet  werden.  

o 

Wenn  man  am  Ende  der  Folge  ankommt,  ohne  das  Suchelement  gefunden  zu  

haben,  wird  als  Ergebnis  ein  spezielles  Element  NO_KEY  zurückgegeben.  

(7)

6  

Sequenzielle  Suche:  Algorithmus  

seqSearch  (F,  k)  → p  

Eingabe:    Folge  F  der  Länge  n,  Suchschlüssel  k  

Ausgabe:    PosiLon  p  des  ersten  Elements  aus  F,  das  gleich  k  ist,  sonst  NO_KEY   for  i:=  1  to  n  

       if  F[i]  =  k  then  return  i;  

       fi;  

od  

return  NO_KEY  

(8)

7  

Aufwand  

WichLgstes  Kriterium  für  Beurteilung  von  Suchverfahren:  

Aufwand.  

 

Was  ist  das  Aufwand  bzw.  wie  wird  der  Aufwand  berechnet?  

¤ 

Notwendige  Schrine  mit  den  Vergleichen  =  Anzahl  der  Schleifendurchläufe.  

¤ 

Der  Aufwand  wird  (sinnvoller  Weise)  nicht  absolut  betrachtet,  sondern  in  

Abhängigkeit  von  der  Länge  n  der  Folge.  

(9)

8  

Sequenzielle  Suche:  Aufwand  

Anzahl der Vergleiche

bester Fall

schlechtester Fall

Durchschnitt (erfolgreiche Suche) Durchschnitt (erfolglose Suche)

1 n n/2

n

(10)

9  

Sequenzielle  Suche:  Java-­‐Programm  1/2  

package ads_seqSearch;

import static gdi.MakeItSimple.*;

class seqSearch {

public final static int NO_KEY = -1;

static int search (int [] array, int key) { for (int i = 0; i < array.length; i++) if (array[i] == key) return i;

return NO_KEY;

}

// .... Fortsetzung nächste Seite

Such- funktion

(11)

10  

Sequenzielle  Suche:  Java-­‐Programm    2/2  

// ... Fortsetzung: Hauptprogramm //

public static void main(String[] args) { int [] F = {2, 4, 5, 6, 7, 8, 9, 11};

int i, key = 1;

print("search key = ");

key = readInt();

println ("search result: " + seqSearch (F, key));

} }

 

Aufruf der Suchfunktion

(12)

11  

Sequenzielle  Suche:  Java-­‐Programm    

package ads_seqSearch;

import static gdi.MakeItSimple.*;

public static void main(String[] args) { int [] F = {2, 4, 5, 6, 7, 8, 9, 11};

int key = 1;

int res = NO_KEY ; int i = 0;

print("search key = ");

key = readInt();

while (i < F.length && res == NO_KEY) { if (F[i] == key) res = i;

i++;

}

println ("search result: " + res);

} }

(13)

12  

Binäre  Suche:  Beschreibung  des  Algorithmus  

1.  Wähle  den  minleren  Eintrag  und  prüfe,  ob  gesuchter  Wert  in  der  ersten  oder  in   der  zweiten  HälDe  der  Folge  ist.  

2.  Fahre  analog  Schrin  1.  mit  der  HälDe  fort,  in  der  sich  der  Eintrag  befindet.  

Realisierungsvarianten:  

   iteraLv  oder  rekursiv.  

(14)

13  

Binäre  Suche:  Algorithmus  

binarySearch  (F,  k)  → p  

Eingabe:    Folge  F  der  Länge  n,  Suchschlüssel  k  

Ausgabe:    PosiLon  p  des  ersten  Elements  aus  F,  das  gleich  k  ist,  sonst  NO_KEY   u  :=  1;  o  :=  n;  

while  u  <=  o    

   m  :=  (u+o)/2;  

 if  F[m]  =  k  then  return  m;    //  gefunden  !    else  if  k  <  F[m]  then  

   o  :=  m  –  1;          //  suche  in  der  unteren  HälDe  weiter      else    

   u  :=  m  +  1;          //  suche  in  der  oberen  HälDe  weiter      fi;  

 fi;  

od;  

return  NO_KEY  

(15)

14  

Binäre  Suche:  Beispiel  

0 1 2 4 5 8 9 12 13 18

u m o

0 1 2 4 5 8 9 12 13 18

u m o

0 1 2 4 5 8 9 12 13 18

o m

1 2 3 4 5 6 7 8 9 10

Suche nach Schlüssel: 8

u

(16)

15  

Binäre  Suche:  Aufwand  

Anzahl der Vergleiche

bester Fall

schlechtester Fall

Durchschnitt (erfolgreiche Suche) Durchschnitt (erfolglose Suche)

1

log

2

n

log

2

n

log

2

n

(17)

16  

Binäre  Suche:  Java-­‐FunkLon  

static int search (int [] array, int key) { int u = 0, o = array.length - 1;

while (u <= o) {

int m = (u + o) / 2;

if (array[m] == key) return m; // gefunden !

else if (key < array[m])

o = m-1; // suche in der unteren Hälfte weiter

else u = m+1; // suche in der oberen Hälfte weiter

}

return NO_KEY;

}

(18)

17  

Binäre  Suche  vs.  sequenzielle  Suche   (im  Minel)  

≈ 13.3

≈ 9.9

≈ 6.6

≈ 3.3 binär

(log2 n)

≈ 5000

≈ 500

≈ 50

≈ 5 sequenziell

(n/2)

10.000 (10 4) 1.000 (103)

100 (102) 10

Anz. Elemente Verfahren

(19)

18  

SorLeren  

o 

Aufgabe  (in  der  Praxis):  Ordnen  von  Dateien  mit  Datensätzen,  die  Schlüssel   enthalten.  

o 

Umordnung  der  Datensätze,  dass  eine  klar  definierte  Ordnung  der  Schlüssel   entsteht.  

o

Viele  Anwendungen  setzen  -­‐  aus  unterschiedlichen  Gründen  -­‐  sorLerte   Datenmengen  voraus:  

¤ 

Kontoauszüge  nach  Kontonummer.  

¤ 

Prüfungsnoten  nach  Matrikelnummer.  

¤ 

Buchausleihe  nach  Namen.  

¤ 

Das  Suchen  wird  schneller.  

(20)

19  

SorLeren:  Grundbegriffe  

o 

Interne  Verfahren  

¤ 

Beim  SorLeren  von  Hauptspeicherstrukturen  (z.B.  Felder).  

¤ 

Voraussetzung:  die  zu  sorLerende  Folge  passt  in  den  Hauptspeicher.  

o 

Externe  Verfahren  

¤ 

Wenn  der  Hauptspeicher  nicht  ausreicht.  

¤ 

Es  wird  auf  einem  externen  Speichermedium  sorLert:  Festplane,   Magnetband.  

o 

Stabilität  eines  SorLerverfahrens  

¤ 

Sind  2  Schlüssel  gleich,  dann  wird  die  relaLve  Reihenfolge  beibehalten.  

(21)

20  

SorLeren:  Stabilität  -­‐  Beispiel  

Name Alter

Abel, Günther 65 Krämer, Willy 52 Stein, Erwin 48 Urschel, Karin 24 Winter, Gerd 52

Name Alter

Urschel, Karin 24 Stein, Erwin 48 Krämer, Willy 52 Winter, Gerd 52 Abel, Günther 65

Sortierkriterium

Sortierkriterium

Die Reihenfolge bleibt unverändert.

(22)

21  

Gruppenarbeit  

o 

Aufgabe:  SorLeren  von  Spielkarten  (z.B.  

Skatspiel  –  französisches  Blan).  Acht   Karten  reichen  aus.  

o 

Ziel:  Formulierung  eines  Algorithmus  in   Pseudocode  zum  SorLeren  einer  Folge  von   Spielkarten  der  Länge  n.  

o 

Vorher:  DefiniLon  der  Rahmen-­‐

bedingungen,  d.h.  wodurch  ist  die  

SorLerreihenfolge  gegeben;  definieren  Sie  

eine  „größer“-­‐Beziehung.  

(23)

22  

SorLeren  durch  SelekLon  –  SelecLon  Sort  

o

Vorgehensweise  kann  auch  beim  SorLeren  von  Spielkarten  angewandt  werden.  

o

SorLeren  eines  Arrays  (=  Stapel):  

¤ 

Suche  das  größte  Element.  

¤ 

Füge  dieses  Element  am  Ende  des  Stapels  ein.  

¤ 

Dies  wird  in  jedem  Schrin  mit  einem  jeweils  um  1  verkleinerten  

Bereich  des  Stapels  ausgeführt,  solange  bis  der  Stapel  die  Länge  1  hat.  

Somit  sammeln  sich  am  Ende  des  Stapels  die  bereits  sorLerten  

Elemente.  

(24)

23  

SelecLon  Sort:  Algorithmus  

SelecMonSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n   p  :=  n;  

while  p  >  1  do  

 g  :=  Index  des  größten  Elementes  aus  F  im  Bereich  1  –  p;  

 Vertausche  Werte  von  F[p]  und  F[g];  

 p  :=  p-­‐1;  

od

 

(25)

24  

SelecLon  Sort:  Beispiel  

44 6 55 30 18 94 44 6 55 30 94 18

44 6 18 30 55 94

30 6 18 44 55 94

18 6 30 44 55 94

6 18 30 44 55 94

Ursprüngliche Schlüssel

Nach dem 1. Durchlauf

Nach dem 2. Durchlauf

Nach dem 3. Durchlauf

Nach dem 4. Durchlauf

Nach dem 5. Durchlauf

(26)

25  

SelecLon  Sort:  Programm  1/2  

static void SelectionSort (int [] array) { int marker = array.length - 1;

while (marker > 0) {

// Suche größtes Element

int max = 0;

// ... das ist zunächst das erste Element

for (int i = 1; i <= marker; i++)

// Suche in Restfolge

if (array [i] > array [max])

// größeres Element gef.

max = i;

swap (array, marker, max);

// Tausche array[marker] mit dem gefundenen Element

marker--;

}

}

(27)

26  

SelecLon  Sort:  Programm  2/2  

static void swap (int [] array, int idx1, int idx2)

// Hilfsmethode zum Vertauschen zweier Feldelemente

{

int tmp = array[idx1];

array[idx1] = array[idx2];

array[idx2] = tmp;

}  

(28)

27  

SorLeren  durch  Einfügen  –  InserLon  Sort  

o 

Typische  menschliche  Vorgehensweise  –  etwa  beim  SorLeren  von   Spielkarten:  

1.  Beginne  mit  der  ersten  Karte  einen  neuen  Stapel.  

2.  Nimm  jeweils  die  nächste  Karte  des  Originalstapels  und  füge  diese  an   der  richLgen  Stelle  in  den  neuen  Stapel  ein.  

•  Sortieren eines Arrays bzw. einer Folge (= Stapel):

–  Das erste Element ist bereits sortiert.

–  Der Zielstapel hat bis jetzt die Länge 1.

–  Beginnend ab dem 2. Element wird an der passenden Stelle in den Ziel- stapel eingefügt.

–  Muss ein Element an einer Stelle dazwischen geschoben werden, dann werden die rechts davon liegenden Elemente jeweils um eine Position nach rechts geschoben.

(29)

28  

InserLon  Sort:  Algorithmus  

InserMonSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n  

for  i  :=  2  to  n  do      //  Element  an  PosiLon  i  wird  an  der  passenden  Stelle  eingefügt      m  :=  F[i];    //  merke  einzufügendes  Element  

   j  :=  i;  

   while  j  >  1  do  //  laufe  von  rechts  nach  links    

     if  F[j-­‐1]  >=  m  then      //  verschiebe  F[j-­‐1]  eine  PosiLon  nach  rechts  

   F  [j]  :=  F[j-­‐1];  

   j  :=  j-­‐1;  

 else    

   Verlasse  innere  Schleife  (=  while-­‐Schleife)  //  weil  EinfügeposiLon  gefunden            fi;  

   od;    //    while-­‐Schleife  

   F  [j]  :=m;  //  gemerktes  Element  an  der  richLgen  PosiLon  einfügen   od;    //  for-­‐Schleife  

(30)

30  

InserLon  Sort  -­‐  Beispiel  

6 44 55 30 94 18 44 6 55 30 94 18

6 44 55 30 94 18

6 30 44 55 94 18

6 30 44 55 94 18

6 18 30 44 55 94 Ursprüngliche Schlüssel

Nach dem 1. Durchlauf

Nach dem 2. Durchlauf

Nach dem 3. Durchlauf

Nach dem 4. Durchlauf

Nach dem 5. Durchlauf

sortiert

(31)

31  

InserLon  Sort:  Programm  

static void insertionSort (int [] array) { for (int i = 1; i < array.length; i++) { int j = i;

int m = array[i];

// Marker-Feld

while (j > 0 && array [j-1] > m) {

// Verschiebe alle größeren Elemente nach hinten

array [j] = array [j-1];

j--;

}

// Setze m auf das freie Feld

array[j] = m;

}

}

(32)

32  

SorLeren  durch  Vertauschen  –  Bubble  Sort  

o 

Man  vergleicht  paarweise  immer  2  benachbarte  Elemente  miteinander.  

o 

Entsprechen  diese  Elemente  nicht  der  SorLerreihenfolge,  dann  vertauscht  man   sie.  

o 

Elemente,  die  größer  sind  als  ihr  Nachfolger  überholen  diese  und  steigen  zum   Ende  der  Folge  hin.  

o 

Man  stellt  sich  die  sorLerende  Folge  verLkal  angeordnet  vor,  dann  kann  man  sich   verschieden  große,  aufsteigende  (LuD-­‐)  Blasen  (bubbles)  vorstellen.  Wie  in  einer   Flüssigkeit  sorLeren  sich  diese  alleine,  da  die  größeren  Blasen  die  kleineren  

überholen.  

(33)

33  

Bubble  Sort:  1.  Algorithmus  

BubbleSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n   for  j  :=  1  to  n  do  

   for  i  :=  1  to  n-­‐1  do          if  F[i]    >  F[i+1]  then  

           Vertausche  Werte  von  F[i]  und  F[i+1];  

       fi;  

   od;  

od;

 

(34)

34  

Bubble  Sort:  2.  Algorithmus  

BubbleSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n   do  

   for  i  :=  1  to  n  -­‐1  do          if  F[i]    >  F[i+1]  then  

           Vertausche  Werte  von  F[i]  und  F[i+1];  

       fi;  

   od  

while  Vertauschungen  staQ  gefunden  haben  

(35)

35  

Bubble  Sort:  3.  Algorithmus  

BubbleSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n   for  j  :=  1  to  n  do  

   for  i  :=  1  to  n  -­‐  j  do          if  F[i]    >  F[i+1]  then  

           Vertausche  Werte  von  F[i]  und  F[i+1];  

       fi;  

   od;  

od;

 

 

(36)

36  

Bubble  Sort:  Beispiel  

6 44 55 30 94 18 44 6 55 30 94 18

6 44 30 55 94 18

Ursprüngliche Schlüssel

Nach dem 1. Durchlauf

Nach dem 2. Durchlauf

Nach dem 3. Durchlauf Nach dem 4. Durchlauf

6 44 30 55 18 94

6 30 44 55 18 94

6 30 44 18 55 94

6 30 18 44 55 94

6 18 30 44 55 94

(37)

37  

Bubble  Sort:  Programm  (zu  2.  Algorithmus)  

static void BubbleSort (int [] array) { boolean swapped;

do {

swapped = false;

for (int i = 0; i < array.length - 1; i++) { if (array [i] > array [i+1]) {

swap (array, i, i+1);

// tausche Elemente

swapped = true;

} }

} while (swapped);

// solange noch Vertauschung

}

(38)

38  

SorLeren  durch  Mischen  –  Merge  Sort  

o 

Externes  Verfahren  –  wenn  Dateien  nicht  in  den  Hauptspeicher  passen.    

o 

SorLeren  in  2  Schrinen:  

¤ 

Die   Folge   wird   in   Teile   zerlegt,   die   jeweils   in   den   Hauptspeicher   passen   und   daher  getrennt  voneinander  mit  internen  Verfahren  sorLert  werden  können.  

Diese  sorLerten  Teilfolgen  werden  wieder  in  Dateien  ausgelagert.  

¤ 

Anschließend   werden   die   Teilfolgen   parallel   einlesen   und   gemischt,   indem   jeweils   das   kleinste   Element   aller   Teilfolgen   gelesen   und   die   neu   Folge   (d.h.  

wieder  eine  Datei)  geschrieben  wird.  

o

Der   Merge   Sort   ist   in   der   Praxis   eine   Mischung   aus   internem   und   externem  

SorLeren.   Für   kleine   Datenmengen   kann   man   den   Merge   Sort   als   rein   internes  

Verfahren  (mit  einem  Array)  realisieren.  

(39)

39  

Gruppenarbeit  

o  Aufgabe:  SorLeren  von  Spielkarten  (z.B.  Skatspiel  –   französisches  Blan),  wobei  Sie  nicht  alle  Spielkarten   gleichzeiLg  zugreifen  (sehen)  können.  Acht  Karten   reichen  aus.  

o  Ziel:  Formulierung  eines  Algorithmus  in  Pseudocode  zum   SorLeren  einer  Folge  von  Spielkarten  der  Länge  n.  

o  Zu  beachten:  

¤  Legen  Sie  fest  wodurch  ist  die  SorLerreihenfolge  gegeben  ist.  

¤  Die  Spielkarten  liegen  alle  auf  einem  Stapel  der  auf  2  Stapel   verteilt  werden  kann.  

¤  Für  das  SorLeren  liegen  die  Spielkarten  jetzt  auf  2  Stapeln.  

¤  Sie  können  immer  nur  die  oberste  Karte  des  Stapels  sehen.  

¤  Die  Spielkarten  können  wieder  auf  einen  (drinen)  Stapel   gelegt  werden.  

o  Denken  Sie  daran,  dass  immer  eindeuLge  Einzelschrine   ausgeführt  werden  können,  die  präzise  beschrieben   werden  müssen.  

(40)

40  

Merge  Sort:  Algorithmus  (grob)  

1.  Zerlege  die  Folge  F  in  zwei  HälDen  F

1

 und  F

2  

.  

2.  Mische  F

1

 und  F

2

 durch  KombinaLon  einzelner  Elemente  zu  geordneten  Paaren.  

3.  Bezeichne  die  gemischte  Sequenz  mit  F  und  wiederhole  die  Schrine  1  und  2,   wobei  dieses  Mal  die  geordneten  Paare  zu  geordneten  Quadrupeln  

zusammengefasst  werden.  

4.  Wiederhole  die  voranstehenden  Schrine  durch  Mischen  der  Quadrupel  zu   Octupeln  und  fahre  damit  solange  fort,  indem  jedes  Mal  die  Längen  der  

gemischten  Sequenzen  verdoppelt  werden,  bis  die  ganze  Sequenz  geordnet  ist.  

(41)

41  

Merge  Sort:  Algorithmus  

MergeSort  (F)      //  sogenanntes  reines  oder  direktes  Mischen     Eingabe:    zu  sorLerende  Folge  F  der  Länge  n  (n  ist  2-­‐er  Potenz)    

tl  :=  1;  //  aktuelle  Lauflänge   while  tl  <  n  do  

   Schreibe  von  der  Folge  F  jeweils  einen  Lauf  alternierend  auf    F1  und  F2,  bis  alle  Läufe  von  F  nach  F1  und  F2,  kopiert  sind.    

   F  :=  leere  Folge;  //  Setze  F  auf  die  AusgangsposiLon  zurück  –  zum  Überschreiben;  

   for  1.  Lauf  to  letzter  Lauf  do  

           while  Lauf  der  Länge  tl  in  F1  oder  F2  noch  nicht  abgearbeitet  do                  En•erne  das  kleinere  Anfangselement  aus    F1  bzw.  F2;  

               Füge  dieses  Element  an  F  an;  

           od  

           Füge  den  verbliebenen  nichtleeren  Rest  des  aktuellen  Laufs  von  F1  oder  F2  an  F  an;  

   od  

       tl  :=  tl  *  2;  //  verdopple  Lauflänge  für  nächsten  Durchlauf   od  

(42)

42  

Merge  Sort:  Beispiel  

44 55 12 42 94 18 6 67

44 12 94 6

55 42 18 67

(44 55) (12 42) (18 94) (6 67) (44 55) (18 94)

(12 42) (6 67)

(12 42 44 55) (6 18 67 94)

(12 42 44 55) (6 18 67 94)

(6 12 18 42 44 55 67 94)

Merge

Split

Split Merge

Merge

Split

Run / Lauf

(43)

43  

Merge  Sort:  EigenschaDen  

o 

Da  eine  Folge  der  Länge  N  in  2  Teilfolgen  zerlegt  wird  und  dann  wieder   zusammengefügt  wird,  nennt  man  das  Verfahren  auch  2-­‐Wege-­‐Mergesort.  

o 

Beginnt  man  mit  Teilfolgen  der  Länge  1  und  fährt  solange  in  2-­‐er-­‐Potenzen  fort,   bis  man  Teilfolgen  der  Länge  N/2  zu  einer  (Ergebnis-­‐)  Folge  der  Länge  N  

zusammengefügt  hat  (wie  im  Algorithmus  angegeben),  dann  nennt  man  das   Verfahren  reines  2-­‐Wege-­‐Mergesort  (straight  2-­‐way  merge  sort).  

o 

Der  reine  2-­‐Wege  Mergesort  ist  ineffizient,  da  er  immer  mit  einelemenLgen   Teilfolgen  beginnt  und  nicht  eine  VorsorLerung  nutzt  und  auf  möglichst  langen   vorsorLerten  Teilfolgen  au‚aut.  Ein  Verfahren,  das  dies  umsetzt,  nennt  man   natürlichen  2-­‐Wege  Mergesort.  

o 

Weitere  Mergesort-­‐Varianten  sind:  

¤ 

Mehr-­‐Wege-­‐Mergesort  

¤ 

Mehrphasen-­‐Mergesort    

(44)

44  

Natürlicher  Merge  Sort:  Algorithmus  

NaturalMergeSort  (F)      //  sogenanntes  natürliches  Mischen     Eingabe:    zu  sorLerende  Folge  F  der  Länge  n  

 

while  Anzahl  der  Läufe  auf  dem  Zielband  F  >  1  do  

   Teile  Folge  F  in  2  Folgen  F1  und  F2  mit  jeweils  maximalen  Lauflängen  auf;  

   F  :=  leere  Folge;  //  Setze  F  auf  die  AusgangsposiLon  zurück  –  zum  Überschreiben;  

   for  1.  Lauf  to  letzter  Lauf  do  //  Solange  noch  eine  der  beiden  Folgen  einen  Lauf  enthält    while  Lauf  in  F1  oder  F2  noch  nicht  abgearbeitet  do  

                 En•erne  das  kleinere  Anfangselement  aus    F1  bzw.  F2;                    Füge  dieses  Element  an  F  an;  

           od  

           Füge  den  verbliebenen  nichtleeren  Rest  des  aktuellen  Laufs  von  F1  oder  F2  an  F  an;  

   od   od  

(45)

45  

Natürlicher  Merge  Sort:  Beispiel  

17  31  5  59  13  41  43  67  11  23  29  47  3  7  71  2  19  57  37  61   (17 31) (13 41 43 67) (3 7 71) (37 61)

(5 59) (11 23 29 47) (2 19 57)

(5 17 31 59) (11 13 23 29 41 43 47 67) (2 3 7 19 57 71) (37 61) (5 17 31 59) (2 3 7 19 57 71)

(11 13 23 29 41 43 47 67) (37 61)

(5 11 13 17 23 29 31 41 43 47 59 67) (2 3 7 19 37 57 61 71) (5 11 13 17 23 29 31 41 43 47 59 67)

(2 3 7 19 37 57 61 71)

(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 57 59 61 67 71)

Merge

Split

Split Merge

Merge

Split

(46)

46  

Natürlicher  Merge  Sort:  2.  Beispiel  

3  2  5  11  7  13  19  17  23  31  29  37  43  41  47  59  57  61  71  67   (3) (7 13 19) (29 37 43) (57 61 71)

(2 5 11) (17 23 31) (41 47 59) (67)

(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 57 59 61 67 71)

Merge

Split

(47)

47  

Weitere  SorLerverfahren  

o 

Es  gibt  ein  ganze  Reihe  weiterer  SorLerverfahren  (z.B.):  

¤ 

Radixsort    -­‐  mit  Fachverteilung,  

¤ 

Quicksort,  

¤ 

SorLeren  mit  Bäumen  -­‐  Heapsort  

¤ 

und  eine  Reihe  von  VariaLonen  dieser  und  der  vorgestellten   Verfahren.  

o 

Welches  Verfahren  letztendlich  für  ein  Problem  eingesetzt  wird,  ist  abhängig  von  

der  konkreten  Aufgabenstellung,  den  Randbedingungen  und  der  Effizienz  des  

jeweiligen  Verfahrens.  

(48)

48  

QuickSort  -­‐  Grundidee  

o 

Zerlegung  der  zu  sorLerenden  Folge  in  2  Teile  bzw.  Teilfolgen.  

o 

Alle  Elemente  der  einen  Folge  sind  kleiner  als  ein  Referenzelement  –  das  sog.  

Pivot-­‐Element  –  und  alle  Elemente  der  anderen  Folge  sind  größer  als  das   Referenzelement  .  

o 

Das  Pivot-­‐Element  kann  beliebig  gewählt  werden  (das  erste,  das  letzte,  das   minlere).  

o 

Für  die  Teilfolgen  wird  dasselbe  Prinzip  angewendet  (→ Rekursion).  

o 

Das  Verfahren  endet  dann  (Rekursionsende),  wenn  die  zu  sorLerende  Folge  die  

Länge  0  hat.  

(49)

49  

QuickSort  –  Algorithmus  Variante  1  (1)  

QuickSort  (F,  u,  o)  

Eingabe:    zu  sorLerende  Folge  F,                                  untere  und  obere  Grenze  u,o   if  o  >  u  then  

     i  :=  Zerlege  (F,  u,  o);  

     QuickSort  (F,  u,  i)        QuickSort  (F,    i+1,  o)   fi  

(50)

50  

QuickSort  –  Algorithmus  Variante  1  (2)  

Zerlege  (F,  u,  o)  returns  integer  //  Ordnet  F  bzgl.  des  minleren  Elements   Eingabe:    zu  sorLerende  Folge  F,  

                                 untere  und  obere  Grenze  u,o   Ausgabe:    PosiLon  z  der  Zerlegung  

p:=  (u+o)/2;    //  Index  des  minleren  Elements  (Pivotelement)   piv  :=  F[p];      //  Pivotelement  

while  u  <=  o  do  

 l  :=  Index  des  ersten  Elements  ab  PosiLon  u  mit  F[l]  >=  piv;  

   r  :=  Index  des  letzten  Elements  unterhalb  PosiLon  o  (inkl.  o)  mit  F[r]  <=  piv;  

 if  l  <  r  then    //  sollten  sich  l  und  r  überschninen  haben,  ist  die  Anordnung  bereits  richLg      Tausche  F[l]  und  F[r];  

   u  :=  l+1;  

   o  :=  r-­‐1;  

 else  return  r;    //  schon  ferLg,  wenn  l  und  r  sich  überschninen  haben    fi  

od  

return  o;  

(51)

51  

QuickSort  –  Beispiel  (mit  Variante  1)  

44 6 55 30 94 18

Ursprüngliche Schlüssel

44 6 18 30 94 55

1. Rekursionsstufe (2 mal)

6 44 18 30 55 94

2. Rekursionsstufe

6 18 44 30 55 94

3. Rekursionsstufe

6 18 30 44 55 94

Sortiertes Feld

(52)

53  

QuickSort  –  Algorithmus  Variante  2  (1)  

QuickSort  (F,  u,  o)  

Eingabe:  zu  sorLerende  Folge  F,  

                             untere  und  obere  Grenze  u,  o   if  o  >  u  then  

     i  :=  Zerlege  (F,  u,  o);  

     QuickSort  (F,  u,  i-­‐1)        QuickSort  (F,    i+1,  o)   fi  

Pivot- Position wird

ausgelassen

Idee:

Das Pivot-Element wird an die „richtige“ Stelle gesetzt. D.h. links, vom Pivot-Element stehen alle Werte <= Pivot-Element und rechts, alle Werte > Pivot-Element.

Das funktioniert nur dann, wenn man beispielsweise das am weitesten rechts stehend Element als Pivot-Element wählt. Dann vertauscht man, ähnlich dem 1.

Algorithmus, solange bis sich die beiden Zeiger überschnitten haben. Danach, wird das Pivot-Element an die richtige Position getauscht.

(53)

54  

QuickSort  –  Algorithmus  Variante  2  (2)  

Zerlege  (F,  u,  o)  returns  integer  //  Ordnet  F  bzgl.  des  am  weitesten  rechts  stehenden  Elements   Eingabe:    zu  sorLerende  Folge  F,  

                                 untere  und  obere  Grenze  u,  o   Ausgabe:  PosiLon  z  der  Zerlegung  

p:=  o;    //  Index  des  am  weitesten  rechts  stehenden  Elements  (Pivotelement)   piv  :=  F[p];      //  Pivotelement  

while  u  <=  o  do  

   l  :=  Index  des  ersten  Elements  ab  PosiLon  u  mit  F[l]  >  piv;  //  wenn  kein  Element  >  piv,  dann  l  =  p  

   r  :=  Index  des  letzten  Elements  unterhalb  PosiLon  o  mit  F[r]  <=  piv;    //  wenn  kein  Element  <=  piv,  dann  r  =  u-­‐1      if  l  <  r  then    //  sollten  sich  l  und  r  überschninen  haben,  ist  die  Anordnung  bereits  richLg  

       Tausche  F[l]  und  F[r];  

       u  :=  l+1;  

       o  :=  r-­‐1;  

   else    

 Tausche  F[l]  und  F[p];  

 return  l;    //  schon  ferLg,  wenn  l  und  r  sich  überschninen  haben      fi  

od  

Tausche  F[u]  und  F[p];  //  Pivotelement  an  die  richLge  Stelle  bringen   return  u;  

(54)

55  

QuickSort  –  Algorithmus  Variante  3  (1)  

QuickSort  (F,  u,  o)  

Eingabe:  zu  sorLerende  Folge  F,  

                             untere  und  obere  Grenze  u,  o   if  o  >  u  then  

     i  :=  Zerlege  (F,  u,  o);  

     QuickSort  (F,  u,  i-­‐1)        QuickSort  (F,    i+1,  o)   fi  

Idee:

Wie bei der 2. Variante wird das Pivot-Element wird an die „richtige“ Stelle gesetzt.

Anders ist hier nur Art des Tausches von Elementen.

Man läuft mit 2 versetzen Zeigern von links nach rechts und tauscht über diese Zeiger referenzierte Elemente, wenn der vordere Zeiger auf ein Element kleiner als das Pivot-Element trifft. Am Ende wird das Pivot-Element an die richtige Position getauscht.

Pivot- Position wird

ausgelassen

(55)

56  

QuickSort  –  Algorithmus  Variante  3  (2)  

Zerlege  (F,  u,  o)  returns  integer  //  Ordnet  F  bzgl.  des  am  weitesten  rechts  stehenden  Elements   Eingabe:    zu  sorLerende  Folge  F,  

                                 untere  und  obere  Grenze  u,  o   Ausgabe:  PosiLon  z  der  Zerlegung  

p  :=  o;    //  Index  des  am  weitesten  rechts  stehenden  Elements  (Pivotelement)   index  :=  u;      //  index  und  zeiger  laufen  jeweils  von  links  nach  rechts  

for  zeiger  :=  u  to  o-­‐1  do  

 if  F[zeiger]  <=  F[p]  then    

   Tausche(F[index],  F[zeiger]);  

   index  :=  index  +  1;  

 fi   od  

Tausche(F[index],  F[p]);      //  Pivotelement  an  die  richLge  Stelle  bringen   return  index;    

(56)

58  

QuickSort  -­‐  Hinweise  

Zur  Programmierung:  

o 

QuickSort   ist   sehr   empfindlich   gegen   minimale   Programmänderungen.   Jede   Version   einer   ImplemenLerung   muss   sorgfälLg   darauƒin   überprüD   werden,   ob   sie  auch  wirklich  in  allen  Fällen  das  korrekte  Ergebnis  liefert.  

[Onmann,Widmayer]  

  Verschiedene  QuickSort-­‐Varianten  unterscheiden  sich:  

o 

In  der  Erminlung  der  Zerlegung.  

o 

In  der  Berechnung  des  Pivot-­‐Elements.  

(57)

59  

Merge  Sort  –  Variante  für  internes  SorLeren  

Idee:  Übertragung  des  Verfahren    für  externes  Mischen  auf  Mischen  mit  einem  Array.  

Vorgehen  ähnlich  wie  beim  QuickSort.  

Vorgehensweise:  

1.  Zu  sorLerende  Folge  wird  in  2  Teilfolgen  zerlegt.  

2.  Wenn  diese  beiden  Teilfolgen  sorLert  sind,  dann  mischt  man  sie  zur  sorLerten  Gesam•olge.  

3.  Die  Teilfolgen  werden  rekursiv  solange  weiter  zerlegt,  bis  man  eine  sorLerte  Teilfolge  erhält.  Das  ist   dann,  der  Fall,  wenn  man  bei  Teilfolgen  angekommen  ist,  die  nur  noch  aus  einem  Element  bestehen.  

4.  Beim  Abarbeiten  der  Rekursion  mischt  man  dann  immer  längere  Teilfolgen,  die  beim  rekursiven   Aufsplinen  entstanden  sind,  zusammen  

5.  Am  Ende  erhält  man  die  sorLerte  Gesam•olge.  

 

(58)

60  

Merge  Sort  –  intern  1/2  

Merge  (F1,F2)  returns  Folge  //  mischt  die  Folgen  F1  und  F2    in  die  neue  Folge  F   Eingabe:    zwei  zu  sorLerende  Folgen  F1  und  F2    

Ausgabe:    sorLerte  Folge  F      

F  :=  leere  Folge;  

while  F1  oder  F2  noch  nicht  abgearbeitet  do  

               En•erne  das  kleinere  Anfangselement  aus    F1  bzw.  F2;                  Füge  dieses  Element  an  F  an;  

           od  

           Füge  den  verbliebenen  nichtleeren  Rest  von  F1  oder  F2  an  F  an;  

return  F  

(59)

61  

Merge  Sort  –  intern  2/2  

MergeSort  (F)  returns  Folge  //  internes  Mischen  eines  Arrays   Eingabe:    zu  sorLerende  Folge  F  

Ausgabe:    sorLerte  Folge  FS      

if  F  einelemenLg  then    //  Rekursionsende    return  F  

else  

 teile  F  in  F1  und  F2              //  beim  internen  SorLeren  erfolgt  das  Teilen  durch  Index-­‐Bereiche  

   F1  =  MergeSort  (F1)  

   F2  =  MergeSort  (F2)      return  Merge  (F1,  F2)   fi  

(60)

62  

  4.  Kapitel  Teil  2:  

SorMerverfahren  im  Vergleich  

(61)

63  

SorLerverfahren  im  Vergleich  

o Aufwandsabschätzungen  werden  später  noch  im  Detail  behandelt.  

o  Aber  vorab:  

¤ 

WER  würde  welches  Verfahren  (wozu)  einsetzen?  

¤ 

Gruppenarbeit:  Algorithmen  analysieren  und  bewerten  !  

¤ 

Es  soll  nur  der  Laufzeitaufwand  betrachtet  werden.  

o Einige  Vorbemerkungen:  

¤ 

Der  Laufzeitaufwand  ist  i.w.  durch  die  Anzahl  der  Schlüsselvergleiche  und   die  Anzahl  der  Vertauschungen  besLmmt.  

¤ 

Der  Aufwand  muss  nicht  ganz  genau  erminelt  werden.  Es  reicht  schon  aus,   den  Aufwand  näherungsweise,  d.h.  in  einer  besLmmten  Größenordnung   zu  besLmmen.  So  ist  es  sicherlich  unbedeutend,  wenn  man  beispielsweise   n  -­‐1    durch  n  ersetzt.  Bei  sehr  großen  Werten  von  n  spielt  ein  um  1  

kleinerer  Wert  ganz  sicher  keine  Rolle.  

¤ 

Bei  einer  endgülLgen  Bewertung  der  Verfahren  spielen  Faktoren  wie  die  

Größe  oder  die  Beschaffenheit  des  zu  sorLerenden  Feldes  eine  wichLge  

Rolle.  

(62)

64  

SelecLon  Sort:  Algorithmus  

SelecMonSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n   p  :=  n;  

while  p  >  1  do  

   g  :=  Index  des  größten  Elementes  aus  F  im  Bereich  1  –  p;  

   Vertausche  Werte  von  F[p]  und  F[g]  wenn  p  !  =  g;  

   p  :=  p-­‐1;  

od

 

(63)

65  

SelecLonSort:  EigenschaDen  

o  Man  beginnt  mit  dem  letzten  Element  als  aktuellem  Element  und  geht  bei  jedem  Durchlauf  um   1  nach  links.  Bei  jedem  Durchlauf  wird  das  aktuelle  Element  mit  dem  größten  Element  links   davon  vertauscht.  

o  Die  Anzahl  der  Vergleiche  ist  also  unabhängig  vom  Aussehen  der  Eingabereihenfolge,  egal  ob   die  Folge  schon  sorLert  ist  oder  in  umgekehrter  Reihenfolge  sorLert  ist.  Für  die  Anzahl  der   Vergleiche  ergibt  sich:  

(n-­‐1)  +  (n-­‐2)  +  (n-­‐3)  +  .  .  .  +  2  +  1  =  n  (n  –  1)/2  ≈ n2/2

 

o  Vertauscht  wird  dann,  wenn  ein  größeres  Element  gefunden  wird.  Ist  die  Folge  schon  sorLert   (günsLgster  Fall),  dann  gibt  es  keine  Vertauschungen,  steht  das  kleinste  Element  hinten  und  ist   der  Rest  sorLert  (schlechtester  Fall)  ist  sie  =  n  -­‐  1.  Im  Minel  deshalb  =  n/2.  

o  Das  ergibt  in  der  Summe  für  Vergleiche  und  Vertauschungen  im  MiQel:  

       

≈    n

2

/2  +  n/2  

o  Das  Verfahren  ist  instabil,  wegen  der  Vertauschungen,  dadurch  werden  relaLve  Reihenfolgen   nicht  beibehalten.  

(64)

66  

InserLon  Sort:  Algorithmus  

InserMonSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n  

for  i  :=  2  to  n  do      //  Element  an  PosiLon  i  wird  an  der  passenden  Stelle  eingefügt      m  :=  F[i];    //  merke  einzufügendes  Element  

   j  :=  i;  

   while  j  >  1  do  //  laufe  von  rechts  nach  links    

     if  F[j-­‐1]  >=  m  then      //  verschiebe  F[j-­‐1]  eine  PosiLon  nach  rechts  

   F  [j]  :=  F[j-­‐1];  

   j  :=  j-­‐1;  

 else    

   Verlasse  innere  Schleife  (=  while-­‐Schleife)  //  weil  EinfügeposiLon  gefunden            fi;  

   od;  //    while-­‐Schleife  

   F  [j]  :=m;  //  gemerktes  Element  an  der  richLgen  PosiLon  einfügen   od;    //  for-­‐Schleife  

(65)

67  

InserLonSort:  EigenschaDen  (1)  

o  Man  beginnt  mit  dem  2.  Element  als  aktuellem  Element  und  prüD,  wo  es  links  davon   eingefügt  werden  muss.  Man  fährt  dann  mit  dem  3.  Element  fort.  Solange,  bis  man  beim   letzten  Element  angekommen  ist.  Muss  ein  Element  eingefügt  werden,  dann  werden  alle   anderen  ab  der  EinfügeposiLon  bis  zur  PosiLon  des  aktuellen  Elements  um  eine  PosiLon   nach  rechts  verschoben.  

o  Die  Anzahl  der  Vergleiche  ist  abhängig  von  der  Art  der  Eingabereihenfolge:  ist  die  Folge  in   umgekehrter  Reihenfolge  sorLert  (der  schlechteste  Fall  bzgl.  der  Vergleiche),  dann  werden   alle  Elemente  miteinander  verglichen:  

 1  +  2  +  .  .  .  +  (n-­‐3)  +  (n-­‐2)  +  (n-­‐1)  =  n  (n  –  1)/2  ≈ n

2

/2  

(schlechtester  Fall)

 

o  Sind  die  Elemente  schon  sorLert  (der  günsMgste  Fall  bzgl.  der  Vergleiche),  dann  ist  man  nach   dem  jeweils  ersten  Vergleich  schon  ferLg:  

   1  +  1  +  .  .  .  +  1  =  n  –  1  

 (bester  Fall)

 

o   In  der  Summe:  

   (n-­‐1)  +  1  +  2  +  .  .  .  +  (n-­‐3)  +  (n-­‐2)  +  (n-­‐1)  =  n  (n  +  1)/2  –  1  ≈ n

2

/2  

o  Im  Minel:  

≈    n

2

/4  

(66)

68  

InserLonSort:  EigenschaDen  (2)  

o  Für  die  Verschiebungen  verhält  es  sich  ganz  ähnlich:  

o  Sind  die  Elemente  schon  sorLert  (günsLgster  Fall)  ,  dann  ist  keine  Verschiebung  notwendig.  

o  Sind  die  Elemente  in  umgekehrter  Reihenfolge  (schlechtester  Fall)  sorLert,  dann  sind            1  +  2  +  .  .  .  +  (n-­‐3)  +  (n-­‐2)  +  (n-­‐1)  =  n  

 (n  –  1)/2  ≈ n2/2  Verschiebungen  notwendig  

o  Im  Minel:  ≈    n2/4.  

o  Das  ergibt  in  der  Summe  für  Vergleiche  und  Verschiebungen  im  MiQel:  

       

≈    2   ⋅   n

2

/4  

o  Das  Verfahren  ist  stabil,  weil  bei  den  Verschiebungen  relaLve  Reihenfolgen  nicht  verändert   werden.  

(67)

69  

Bubble  Sort  -­‐  Algorithmus  

BubbleSort  (F)  

Eingabe:    zu  sorLerende  Folge  F  der  Länge  n  (n  >  1)   j  :=  1;  

do    

     for  i  :=  1  to  n  -­‐  j    do                if  F[i]    >  F[i+1]  then  

                   Vertausche  Werte  von  F[i]  und  F[i+1];  

             fi;  

     od;  

j  :=  j  +1;  

while  Vertauschungen  stan  gefunden  haben  und  j  <=  n;

 

 

(68)

70  

BubbleSort:  EigenschaDen  

o  Bei  jedem  Durchlauf  werden  alle  Elemente  paarweise  miteinander  ver-­‐glichen  und  ggf.  

miteinander  vertauscht.  Dabei  wird  das  jeweils  größte  Element  gefunden  und  durch   Vertauschen  mit  seinem  rechten  Nachbarn  an  das  Ende  der  Folge  bewegt.  

o  Die  Anzahl  der  Vergleiche  und  Vertauschungen  ist  abhängig  von  der  An-­‐ordnung  der  

Eingabereihenfolge:  ist  die  Folge  in  umgekehrter  Reihenfolge  sorLert  (der  schlechteste  Fall),   dann  werden  im  i-­‐ten  Durchlauf  n-­‐i  Elemente  miteinander  verglichen  und  vertauscht:  

   2  ⋅  ((n-­‐1)  +  (n-­‐2)  +  (n-­‐3)  +  .  .  .  +  2  +  1)  =  n  (n  –  1)  ≈ n

2

 

o  Ist  die  Folge  schon  sorLert  (der  günsMgste  Fall),  ist  nur  ein  Durchlauf  notwendig:  

   

n-­‐1  Vergleiche  und  keine  Vertauschungen

 

o   In  der  Summe:  

   (n-­‐1)  +  2  ((n-­‐1)  +  (n-­‐2)  +  (n-­‐3)  +  .  .  .  +  2  +  1)  =  n  (n  +  1)  –  1  ≈ n2    

o  Im  Minel:                    

≈    n

2

/2  

o  Zwei  benachbarte  Elemente  werden  nur  dann  getauscht,  wenn  das  erste  Element  größer  ist,   d.h.  das  Verfahren  ist  stabil.  

(69)

71  

Merge  Sort:  Algorithmus  

MergeSort  (F)      //  sogenanntes  reines  oder  direktes  Mischen     Eingabe:    zu  sorLerende  Folge  F  der  Länge  n  (n  ist  2-­‐er  Potenz)    

tl  :=  1;  //  aktuelle  Lauflänge   while  tl  <  n  do  

   Teile  Folge  F  in  der  Mine  in  2  gleich  lange  Folgen  F1  und  F2  auf;  

   F  :=  leere  Folge;  //  Setze  F  auf  die  AusgangsposiLon  zurück  –  zum  Überschreiben;  

   for  1.  Lauf  to  letzter  Lauf  do  

           while  Lauf  der  Länge  tl  in  F1  oder  F2  noch  nicht  abgearbeitet  do                  En•erne  das  kleinere  Anfangselement  aus    F1  bzw.  F2;  

               Füge  dieses  Element  an  F  an;  

           od  

           Füge  den  verbliebenen  nichtleeren  Rest  des  aktuellen  Laufs  von  F1  oder  F2  an  F  an;  

   od  

       tl  :=  tl  *  2;  //  verdopple  Lauflänge  für  nächsten  Durchlauf   od  

(70)

72  

MergeSort:  EigenschaDen  (1)  

o  Die  Anzahl  der  Durchläufe  ist  (beim  reinen  MergeSort)  konstant.  Die  Anzahl  der  OperaLonen   pro  Durchlauf  auch.  

o  Beim  reinen  MergeSort  wird  die  Lauflänge  (beginnend  mit  1)  bei  jedem  Durchlauf  

verdoppelt.  D.h.  dass  man  bei  n  Elementen  (n  ist  eine  2-­‐er  Potenz!  )  log2n  Durchläufe  erhält.  

o  Bei  jedem  Durchlauf  werden  alle  n  Elemente  des  Ausgangsbands  gleichmäßig  auf  die  beiden   Hilfsbänder  verteilt:  2  ⋅  n  /  2  =  n  KopieroperaLonen.  Da  es  log  n  Durchläufe  gibt,  ist  die  

Gesamtzahl  der  KopieroperaLonen  beim  Zerlegen  =  n  

⋅  

log2n.  

o  Beim  Zusammenfügen  der  Läufe  auf  den  Hilfsbändern  werden  

pro  Durchlauf  (Lauflänge-­‐1)  ⋅ n  /  Lauflänge  Vergleiche  gemacht  (beachte:  die  Lauflänge  ist   immer  eine  2-­‐er  Potenz),  um  über  die  Reihenfolge  auf  dem  Ausgangsband  zu  entscheiden.  

Für  die  Gesamtzahl  SV  der  Vergleiche   ergibt  sich  demnach:  

SV  =    (1  ⋅ n  /  2)  +  (3  ⋅  n  /  4)  +  (7  ⋅  n  /  8)  +  .  .  .  +  ((2

log  n  

-­‐1)  ⋅  n  /  2

log  n

)            =    (1  ⋅ n  /  2)  +  (3  ⋅  n  /  4)  +  (7  ⋅  n  /  8)  +  .  .  .  +  ((n-­‐1)  ⋅  n  /  n)  

         =    (1/2  ⋅ n  )  +  (3/4  ⋅  n)  +  (7/8  ⋅  n)  +  .  .  .  +  (n-­‐1)    

(71)

73  

MergeSort:  EigenschaDen  (2)  

o  Jeder  einzelne  Summand  ist  kleiner  als  n,  die  Anzahl  der  Summanden  ist  log  n.  Deshalb  gilt   die  für  die  Summe  (SV)  folgende  Abschätzung:  

SV  <  n  ⋅  log  n  

o  Beim  Zurückschreiben  auf  das  Ausgangsband  gibt  es  genau  n  KopieroperaLonen.  Da  es  log  n   Durchläufe  gibt,  ist  die  Gesamtzahl  der  KopieroperaLonen  beim  Zurückschreiben  =  n  

⋅  

log  n.  

o  Insgesamt  gilt  für  den  Gesamtaufwand  (GA):    

 GA  <=  Anzahl  Durchläufe  

⋅  

(KopieroperaLonen  beim  AuDeilen  +  VergleichsoperaLonen  +   KopieroperaLonen  beim  Mischen  )  

 

≈  log  n   ⋅  (n  +  n  +  n)     ≈ n  ⋅  log  n    

o  Die  relaLve  Ordnung  der  Elemente  bleibt  erhalten,  da  immer  nur  verschoben  und  nicht   getauscht  wird.  Das  Verfahren  ist  also  stabil.  

o  Der  natürliche  MergeSort  hat  auf  jeden  Fall  ein  besseres  Laufzeitver-­‐halten,  da  er  höchstens   genauso  viele  Läufe  hat  wie  der  reine  MergeSort.  

(72)

74  

QuickSort  –  Algorithmus  1.  Variante  1/2  

QuickSort  (F,  u,  o)  

Eingabe:    zu  sorLerende  Folge  F,                                  untere  und  obere  Grenze  u,o   if  o  >  u  then  

     i  :=  Zerlege  (F,  u,  o);  

     QuickSort  (F,  u,  i)        QuickSort  (F,    i+1,  o)   fi  

(73)

75  

QuickSort  –  Algorithmus  1.  Variante  2/2  

Zerlege  (F,  u,  o)      //  Ordnet  F  bzgl.  des  minleren  Elements   Eingabe:    zu  sorLerende  Folge  F,  

                               untere  und  obere  Grenze  u,o   Ausgabe:  PosiLon  z  der  Zerlegung  

p:=  (u+o)/2;    //  Index  des  minleren  Elements  (Pivotelement)   piv  :=  F[p];      //  Pivotelement  

while  u  <=  o  do  

       l  :=  Index  des  ersten  Elements  ab  PosiLon  u  mit  F[l]  >=  piv;  

       r  :=  Index  des  letzten  Elements  unterhalb  PosiLon  o  (inkl.  o)  mit  F[r]  <=  piv;  

       if  l  <  r  then    //  sollten  sich  l  und  r  überschninen  haben,  ist  die  Anordnung  bereits  richLg                  Tausche  F[l]  und  F[r];  

               u  :=  l+1;  

               o  :=  r-­‐1;  

       else  return  r;    //  schon  ferLg,  wenn  l  und  r  sich  überschninen  haben          fi  

od  

return  o;  

Referenzen

ÄHNLICHE DOKUMENTE

Naturschutz appelliert zudem an den Bayerischen Umweltminister Schnappauf, sich nicht an der Nase herum führen zu lassen, er muss sich im Kabinett gegen den

Technisch gesehen, kann schon längere Zeit über eine Russprobe im Kamin festgestellt werden, ob nur Holz verbrannt wird oder auch Haushaltsabfall.. Die Kaminfeger

3 VersG kann eine Versammlung aufgelöst wer- den, wenn sie nicht angemeldet ist, Auflagen nicht eingehalten werden oder die tatsächliche Durchführung von den Angaben in

mit Wurzel ≥ i erf¨ ullen die Heapeigenschaft Nach Aufruf von Build-Heap (A) enth¨ alt A dieselben Eintr¨ age wie zuvor, aber nunmehr bildet A einen heap der Gr¨ oße n....

Diese beiderseitige Erhitzung der zu schweißenden Naht bildet einen wesentlichen Vorzug der Wassergas- schweißung und macht dieselbe daher besonders für überlappte Schweißung

Drei FP-Burschenschafter in der Regierung - Haupt: ,,Extremismus von links derzeit

Eine Aktionsveranstal- tung gegen Rassismus und Ausländerfeindlichkeit unter dem Motto: &#34;Keine neuen Pogrome- schaut nicht länger weg.. die etwas

Eine Aktionsveranstal- tung gegen Rassismus und Ausländerfeindlichkeit unter dem Motto: &#34;Keine neuen Pogrome- schaut nicht länger weg.. die etwas