ACM ICPC Praktikum Kapitel 4: Sortieren Übersicht • • • • • Problem und Anwendungen Bubblesort Bucketsort Mergesort Topologisches Sortieren Problem Sortierproblem: • Gegeben: Folge x1,x2,…,xn • Gesucht: Sortierung :{1,…,n} ! {1,…,n}, so dass x(1) <= x(2) <= … <= x(n) 2 5 1 7 8 4 5 7 8 1 2 4 Anwendungen • Eindeutigkeitstest: Wie können wir testen, dass alle Werte in einer Folge verschieden sind? • Duplikatentfernung: Wie können wir alle bis auf ein Duplikat für jedes Element entfernen? • Scheduling: Eine optimale Regel zum Scheduling von uniformen Jobs mit Deadlines ist “Earliest Deadline First (EDF)”, was eine Sortierung benötigt. • Median: Wir wollen das k-tgrößte Element einer Folge finden. • Häufigkeitszählung: Was ist das am häufigsten vorkommende Element in einer Folge? • Vereinigung oder Schnitt: Ist einfach, wenn die beiden Teilmengen in sortierte Folge gegeben sind. • Gibt es x und y mit x+y=z? Sortiere die Folge S. Laufe mit i aufwärts beginnend mit 1 und mit j abwärts beginnend mit n. Prüfe, ob S[i]+S[j]=z. Falls <, dann erhöhe i, und sonst erniedrige j. Bubblesort • Idee: Vergleich benachbarter Einträge. bubblesort(int s[1..n], int n) { for i=1 to n-1 do { for j=1 to i do if (s[j+1]<s[j]) then swap(s[j],s[j+1]) } } Bucketsort • Idee: falls Werte in ganze Zahlen in [a,b], allokiere Array dafür bucketsort(int s[1..n], int n) { // allocate array num[a..b] for i=a to b do num[i]=0; for i=1 to n do num[s[i]]++; i=1; j=a; while i<=n do { while num[j]=0 do j=j+1; for k=0 to num[j]-1 do s[i+k]=j; i = i+num[j]; } } Mergesort • Idee: verschmelze Teillisten in größer werdende Listen mergesort(int s[1..n], int n) { // n: power of 2, otherwise filled with (MAXINT-1)’s for size=1 to n/2 do { a[size+1] = MAXINT; // a[1..size+1] for one list b[size+1] = MAXINT; // b[1..size+1] for other list for i=1 to n/(2*size) do { // prepare for merging for j=1 to size do a[j] = s[2*(i-1)*size+j]; for j=1 to size do b[j] = s[(2*i-1)*size+j]; k = 1; l=1; // merge for j=2*(i-1)*size+1 to 2*i*size do if a[k]<b[l] then { s[j]=a[k]; k=k+1; } else { s[j]=b[l]; l=l+1; } } } } Suchen in sortierter Folge • Binäre Suche O(log n) Zeit Topologisches Sortieren • Eingabe: azyklischer gerichteter Graph G=(V,E), V={1,…,n} • Ausgabe: Ordnung :{1,…,n} ! {1,…,n} auf Knoten, so dass für alle Kanten (i,j) 2 E gilt (i)<(j). • Algorithmus: Breitensuche, angefangen mit Knoten ohne eingehende Kante. Topologisches Sortieren Datenstrukturen: class edge { node *dest; edge *next; }; class node { int indeg; // # incoming edges edge *out; // link to outg. edges }; toposort(node v[1..n], int s[1..n], int n) { i=1; for j=1 to n do if v[j].indeg=0 then { s[i]=j; i=i+1; } b=1; e=i; // begin and end in s[] while b<e do { for j=b to e-1 do { l = v[s[j]].out; while l<>NULL do { l->dest->indeg--; if l->dest->indeg=0 then { s[i]=l->dest; i=i+1; } l = l->next; } } b = e; e=i; } }} 2-dimensionales Sortieren • Welche Struktur erlaubt schnelle Suche? • Delaunay Triangulierung. • Wird noch in Geometrie behandelt… Problem I Vito’s Familie: • Eingabe: ganze Zahlen s1,…,sr, 0<r<500, 0<si<30000 • Ausgabe: Position p, die Summe der paarweisen Distanzen zu allen si minimiert. Problem II Stacks of Pancakes: • Eingabe: Mehrere Stapel von Pfannkuchen, jeder bestehend aus 1-30 Pfannkuchen. Jeder Pfannkuchen hat ganzzahligen Durchmesser zwischen 1 und 100. • Ausgabe: Sortiere jeden Stapel durch FlipOperationen, wobei Flip(i) alle Pfannkuchen von Position i aufwärts einmal umdreht. Problem III Bridge: • Eingabe: n Personen mit ganzahligen Geschwindigkeiten, um den Fluss zu überqueren. • Ausgabe: Plan mit minimaler Zeit, um alle Personen über den Fluss zu bringen. Die Beschränkung ist, dass es nur ein Boot gibt und höchstens zwei darin sitzen können. Der langsamste bestimmt die Geschwindigkeit des Bootes. Problem III Longest Nap: • Eingabe: Ein Tag mit Terminen, gegeben durch „Zeit1 Zeit2 Termin“. • Ausgabe: Finde längste Pause zwischen den Terminen. Problem IV Shoemaker’s Problem: • Eingabe: N Schuhaufträge, Schuhauftrag i benötigt Ti Tage und für jede Verzögerung um einen Tag muss eine Strafe von Si Cents bezahlt werden. Der Schuhmacher kann nur an einem Schuh pro Tag arbeiten. • Ausgabe: Reihenfolge der Schuhaufträge, die die geringste Strafe verursacht. Problem V CDVII: • Eingabe: Gebührentabelle mit einem Eintrag pro Stunde des Tages und eine Reihe von Enter und Exit Ereignissen, bestehend aus „Nummernschild Monat:Tag:Stunde:Minute“ und der Entfernung zum Ende der Autobahn. Die Rechnung multipliziert die Gebühren mit den gefahrenen Kilometern, enthält einen Dollar pro Fahrt und zwei Dollar als Grundgebühr. • Ausgabe: Gib die Rechungen für die Nummernschilder aus.