ALG 08 Merge sort -- řazení sléváním A4B33ALG 2011/08 ALG 08 Merge sort -- řazení sléváním Heap Sort -- řazení binární haldou Prioritní fronta implementovaná binární haldou
Sluč (slij?) dvě seřazená pole A4B33ALG 2011/08 Merge sort Sluč (slij?) dvě seřazená pole Porovnávané prvky B K M T U Z A D E J O R B K M T U Z A A D E J O R B K M T U Z A B A D E J O R 2
Sluč dvě seřazená pole - pokr. A4B33ALG 2011/08 Merge sort Sluč dvě seřazená pole - pokr. B K M T U Z A B D A D E J O R B K M T U Z A B D E A D E J O R B K M T U Z A B D E J A D E J O R 3
Sluč dvě seřazená pole - pokr. A4B33ALG 2011/08 Merge sort Sluč dvě seřazená pole - pokr. B K M T U Z A B D E J K A D E J O R B K M T U Z A B D E J K M A D E J O R B K M T U Z A B D E J K M O A D E J O R 4
Sluč dvě seřazená pole - pokr. A4B33ALG 2011/08 Merge sort Sluč dvě seřazená pole - pokr. Kopíruj zbytek B K M T U Z A B D E J K M O R A D E J O R Seřazeno B K M T U Z A B D E J K M O R T U Z A D E J O R 5
Rozděl a panuj! Divide and conquer! Divide et impera! A4B33ALG 2011/08 Rozděl a panuj! Divide and conquer! Divide et impera! "Jejich" práce úloha Naše práce Rozděl! úloha úloha úloha Vyřeš částečnou úlohu Vyřeš částečnou úlohu Sluč! Sluč! řešení řešení řešení 6
Merge sort Neseřazeno K Z U B M T E A J R D O Rozděl! K Z U B M T E A A4B33ALG 2011/08 Merge sort Neseřazeno K Z U B M T E A J R D O Rozděl! K Z U B M T E A J R D O Zpracuj oddělěně Process separately seřaď! seřaď! B K M T U Z A D E J O R Panuj! Sluč! A B D E J K M O R T U Z Seřazeno 7
… … … … … … … … Merge sort Neseřazeno K Z U B M T E A J R D O Rozděl! A4B33ALG 2011/08 Merge sort Neseřazeno K Z U B M T E A J R D O Rozděl! K Z U B M T E A J R D O Rozděl! Rozděl! … … … … … … … … Sluč! Sluč! K U Z B M T A E J D O R Sluč! B K M T U Z A D E J O R Seřazeno 8
void merge( int [] in, int [] out, int low, int high ){ A4B33ALG 2011/08 Merge sort void merge( int [] in, int [] out, int low, int high ){ int half = (low+high)/2; int i1 = low; int i2 = half+1; int j = low; // compare and merge while( (i1 <= half) && (i2 <= high) ){ if( in[i1] <= in[i2] ){ out[j] = in[i1]; i1++; } else { out[j] = in[i2]; i2++; } j++; } // copy the rest while( i1 <= half ){ out[j] = in[i1]; i1++; j++; } while( i2 <= high ){ out[j] = in[i2]; i2++; j++; } 9
void mergeSort( int [] a, int [] aux, int low, int high ){ A4B33ALG 2011/08 Merge sort void mergeSort( int [] a, int [] aux, int low, int high ){ int half = (low+high)/2; if( low >= high ) return; // too small! // sort mergeSort( a, aux, low, half ); // left half mergeSort( a, aux, half+1, high ); // right half merge( a, aux, low, high ); // merge halves // (*) put result back to a -- clumsy method! for( int i = low; i <= high; i++ ) a[i] = aux[i]; // (*) better solution: swap references //to a and aux in even depths of recursion } 10
Merge sort - optimalizované využití pomocného pole A4B33ALG 2011/08 Merge sort - optimalizované využití pomocného pole void mergeSort( int [] a ) { int [] aux = Arrays.copyOf( a, a.length ); mergeSort(a, aux, 0, a.length-1, 0 ); } void mergeSort( int [] a, int [] aux, int low, int high, int depth ){ int half = (low+high)/2; if( low >= high ) return; mergeSort( a, aux, low, half, depth+1 ); mergeSort( a, aux, half+1, high, depth+1 ); // note the exchange of a and aux if( d % 2 == 0 ) merge( aux, a, low, high ); else merge( a, aux, low, high ); 11
Asymptotická složitost A4B33ALG 2011/08 Merge sort Asymptotická složitost Rozděl! ........ log2(n) krát Sluč! ........ log2(n) krát Rozděl! ........ (1) operací Sluč! ........ (n) operací (n)· (log2(n)) = (n·log2(n)) operací Celkem ...... Asymptotická složitost Merge sortu je (n·log2(n)) 12
Rozděl! ........ Nepohybuje prvky A4B33ALG 2011/08 Merge sort Stabilita Rozděl! ........ Nepohybuje prvky Sluč! ….... “ if (in[i1] <= in[i2]) { out[j] = in[i1]; …” Zařaď nejprve levý prvek, když slučuješ stejné hodnoty MergeSort je stabilní 13
Halda Pravidlo haldy Heap sort A B D M J T E Z O K R U a c b a c A4B33ALG 2011/08 Heap sort A Halda B D M J T E Z O K R U a c b Pravidlo haldy a c b 14
...... (heap) top ...... vrchol (haldy) A4B33ALG 2011/08 Heap sort Terminologie a c b ...... predecessor, parent of a b c ...... předchůdce, rodič , ...... successor, child of b c a ...... následník, potomek ...... (heap) top ...... vrchol (haldy) A D B 15
Halda uložená v poli Heap sort A B D r T M J E s t Z O K R U A4B33ALG 2011/08 Heap sort Halda uložená v poli A 1 B D 2 3 r T M J E k 4 5 6 7 s t Z O K R U 2k 2k+1 8 9 10 11 12 následníci následníci k 2k 2k+1 1 2 3 4 5 6 7 8 9 10 11 12 s t r A B D M J T E Z O K R U 16
! ! → prohoď B ↔ U Oprava haldy Vrchol odstraněn (1) Vlož na vrchol A4B33ALG 2011/08 Oprava haldy Vrchol odstraněn (1) 3 Vlož na vrchol 1 Odstraň vrchol A 1 A U ! ! B D B D 2 M J T E M J T E Z O K R U Z O K R U > B, U > D, B < D 2 prohoď B ↔ U → poslední první 17
Vlož na vrchol - pokračování A4B33ALG 2011/08 Oprava haldy Vrchol odstraněn (2) 3 Vlož na vrchol - pokračování B B A A J D ! U ! D M U T E M J T E ! ! Z O K R Z O K R U > M, U > J, J < M U > K, U > R, K < R prohoď J ↔ U prohoď K ↔ U 18
Nová halda Oprava haldy Vrchol odstraněn (3) Vlož na vrchol - hotovo B A4B33ALG 2011/08 Oprava haldy Vrchol odstraněn (3) 3 Vlož na vrchol - hotovo 3 B A J D M K T E Z O U R Nová halda 19
! ! → prohoď D ↔ R Oprava haldy Vrchol odstraněn II (1) Vlož na A4B33ALG 2011/08 Oprava haldy Vrchol odstraněn II (1) 3 1 Vlož na vrchol Odstraň vrchol 1 B A R ! B A ! J D J D M K T E M K T E Z O U R Z O U R > J, R > D, D < J prohoď D ↔ R 2 → poslední první 20
Vlož na vrchol - pokračování A4B33ALG 2011/08 Oprava haldy Vrchol odstraněn II (2) Vrchol odstraněn II (3) 3 Vlož na vrchol - pokračování 3 Vlož na vrchol - hotovo B A D B A D J R J E ! M K T E M K T R Z O U Z O U R < T, R > E Nová halda prohoď E ↔ R 21
Heap sort I Neseřazeno R J U Z B T E M O K A D II III A4B33ALG 2011/08 Heap sort I Neseřazeno R J U Z B T E M O K A D II III for (i = 1; i <= n; i++) “odstraň vrchol”; Vytvoř haldu A B D E J M K O R T U Z R K M B D E J A Z O T U IV Z U T R O M K J E D B A Seřazeno 22
Rekurzivní vlastnost "býti haldou" A4B33ALG 2011/08 Rekurzivní vlastnost "býti haldou" A D B M J T E Z O K R U je halda je halda a je halda 23
Vytvoř jednu haldu ze dvou menších A4B33ALG 2011/08 Vytvoř jednu haldu ze dvou menších Z A B halda halda není (ještě) halda Z > A nebo Z > B prohoď: Z ↔ min(A,B) 24
Vytvoř jednu haldu ze dvou menších A4B33ALG 2011/08 Vytvoř jednu haldu ze dvou menších A B Z F C halda halda halda není halda není halda 25
Každý list je samostanou (malinkou) haldou A4B33ALG 2011/08 Vytvoř haldu Stavba haldy zdola Uvaž: Každý list je samostanou (malinkou) haldou 6 Potom: Vytvoř haldu v ... 1 R ... a vytvoř haldu v ... 2 5 4 ... a vytvoř haldu v ... J U 3 3 2 1 ... a vytvoř haldu v ... 4 Z B T E ... a vytvoř haldu v ... 5 ... a vytvoř haldu v ... 6 M O K A D … a celá halda je hotova. 26
Halda uložená v poli Halda v poli A B D r T M J E s t Z O K R U A4B33ALG 2011/08 Halda v poli Halda uložená v poli A 1 B D 2 3 r T M J E k 4 5 6 7 s t Z O K R U 2k 2k+1 8 9 10 11 12 následnící následníci k 2k 2k+1 1 2 3 4 5 6 7 8 9 10 11 12 s t r A B D M J T E Z O K R U 27
Prvky náhodně uspořádány A4B33ALG 2011/08 Tvorba haldy v poli Prvky náhodně uspořádány Pole Není halda 6 6 2 1 3 4 5 6 7 8 9 10 11 12 R R 5 1 5 J J 2 4 4 U U 3 3 3 Z Z 4 2 2 B B 1 5 1 T T 6 E E 7 M M 8 O O 9 K K 10 A A 11 D D 12 28
-- Aktuálně vytvořená halda A4B33ALG 2011/08 Tvorba haldy v poli Přesuny Pole -- Aktuálně vytvořená halda 6 6 2 1 3 4 5 6 7 8 9 10 11 12 R R 5 1 5 J J 2 4 4 U U 3 3 3 Z Z 4 2 2 B B 1 5 1 D D 6 E E 7 M M 8 O O 9 K K 10 A A 11 T T 12 29
-- Aktuálně vytvořená halda A4B33ALG 2011/08 Tvorba haldy v poli Dříve vytvořená halda Přesuny Pole -- Aktuálně vytvořená halda 6 6 2 1 3 4 5 6 7 8 9 10 11 12 R R 5 1 5 J J 2 4 4 U U 3 3 3 Z Z 4 2 2 A A 1 5 1 D D 6 E E 7 M M 8 O O 9 K K 10 B B 11 T T 12 30
-- Aktuálně vytvořená halda A4B33ALG 2011/08 Tvorba haldy v poli Dříve vytvořená halda Přesuny Pole -- Aktuálně vytvořená halda 6 6 2 1 3 4 5 6 7 8 9 10 11 12 R R 5 1 5 J J 2 4 4 U U 3 3 3 M M 4 2 2 A A 1 5 1 D D 6 E E 7 Z Z 8 O O 9 K K 10 B B 11 T T 12 31
-- Aktuálně vytvořená halda A4B33ALG 2011/08 Tvorba haldy v poli Dříve vytvořená halda Přesuny Pole -- Aktuálně vytvořená halda 6 6 2 1 3 4 5 6 7 8 9 10 11 12 R R 5 1 5 J J 2 4 4 D D 3 3 3 M M 4 2 D 2 A A 1 5 1 T T 6 E E 7 Z Z T 8 O O U 9 K K 10 B B 11 U U 12 32
-- Aktuálně vytvořená halda A4B33ALG 2011/08 Tvorba haldy v poli Dříve vytvořená halda Přesuny Pole -- Aktuálně vytvořená halda 6 6 2 1 3 4 5 6 7 8 9 10 11 12 R R 5 1 5 J A 2 4 4 D D 3 3 A 3 M M J 4 2 2 A 1 B 5 1 T T 6 E B E 7 Z Z 8 O O 9 K K 10 B J 11 U U 12 33
-- Aktuálně vytvořená halda A4B33ALG 2011/08 Tvorba haldy v poli Přesuny Pole -- Aktuálně vytvořená halda 6 6 2 1 3 4 5 6 7 8 9 10 11 12 R A 5 1 5 J B 2 4 A 4 D R D 3 3 B 3 M M 4 2 2 A J 1 5 1 T T 6 E E J 7 Z Z 8 O O 9 K K 10 R B 11 U U 12 34
Heap sort A B D M J T E Z O K R U Halda Krok 1 A B D M J T E Z O K R U A4B33ALG 2011/08 Heap sort A B D M J T E Z O K R U Halda Krok 1 A B D M J T E Z O K R U 1 2 3 4 5 6 7 8 9 10 11 12 U B D M J T E Z O K R A B J D M K T E Z O U R A Halda 35
Heap sort Krok k J K R M O T U Z E D B A Z K R M O T U J E D B A K M R A4B33ALG 2011/08 Heap sort Krok k J K R M O T U Z E D B A 1 2 3 4 5 6 7 8 9 10 11 12 Z K R M O T U J E D B A K M R Z O T U J E D B A Halda k 36
void heapSort( Item [] a, int n ) { // create a heap A4B33ALG 2011/08 Heap sort // array: a[1]...a[n] !!!! void heapSort( Item [] a, int n ) { // create a heap for( int i = n/2; i > 0; i-- ) repairTop( a, i, n ); // sort for( int i = n; i > 1; i-- ) { swap( a, 1, i ); repairTop( a, 1, i-1 ); } 37
Heap sort // array: a[1]...a[n] !!!!!! A4B33ALG 2011/08 Heap sort // array: a[1]...a[n] !!!!!! void repairTop( Item [] a, int top, int bottom ) { int i = top; // a[2*i] and a[2*i+1] int j = i*2; // are children of a[i] Item topVal = a[top]; // try to find a child < topVal if( (j < bottom) && (a[j] > a[j+1]) ) j++; // while (children < topVal) // move children up while( (j <= bottom) && (topVal > a[j]) ){ a[i] = a[j]; i = j; j = j*2; // skip to next child } a[i] = topVal; // put topVal where it belongs 38
repairTop operace nejhorší případ ... log2(n) (n=velikost haldy) A4B33ALG 2011/08 Heap sort repairTop operace nejhorší případ ... log2(n) (n=velikost haldy) vytvoř haldu ... n/2 repairTop operací log2(n/2) + log2(n/2+1) + ... + log2(n) (n/2)(log2(n)) = (n·log(n)) (n) lze ukázat ... n/2 repairTop operací ... seřaď haldu ... n-1 repairTop operací, nejhorší případ: log2(n) + log2(n-1) + ... + 1 n · log2(n) = (n·log(n)) (n·log(n)) celkem ... vytvoř haldu + seřaď haldu = Asymptotická složitost Heap sortu je (n·log(n)) (n·log(n)) V praktických situacích se očekává Heap sort není stabilní Otázka: Pro jaká data nastane složitost menší než (n·log(n)) ? 39
Prioritní fronta B J E U T M K X O R A4B33ALG 2011/08 Prioritní fronta Prioritní fronta má stejné operace jako obyčejná fronta - vlož do fronty (Insert, Enqueue, apod), - čti první prvek (Front, Top, apod), - smaž první prvek (Dequeue, Pop, apod). Navíc interně zajišťuje, že na čele fronty je vždy prvek s minimální (maximální) hodnotou ze všech prvků ve frontě. Prioritní frontu lze implementovat pomocí haldy. Plným jménem: "Binární haldy". B J E U T M K X O R 40
Prioritní fronta pomocí binární haldy -- operace A4B33ALG 2011/08 Prioritní fronta pomocí binární haldy -- operace Čti první prvek (Front, Top, apod) . Zřejmé. Smaž první prvek (Dequeue, Pop, apod) = Odstraň vrchol a oprav haldu. Viz výše. Vlož do fronty (Insert, Enqueue, apod). Vložíme prvek na konec fronty (haldy). Ve většině případů se tím poruší pravidlo haldy a je nutno haldu opravit. B J E U T M K X O R A Vlož A 41
Prioritní fronta pomocí binární haldy – vlož prvek A4B33ALG 2011/08 Prioritní fronta pomocí binární haldy – vlož prvek Vlož A B B J E J E U T M K U T M A X O R A X O R K Pravidlo haldy je porušeno, vyměň vkládaný prvek s jeho rodičem. Pravidlo haldy je stále porušeno, vyměň vkládaný prvek s jeho rodičem. 42
Prioritní fronta pomocí binární haldy – vlož prvek A4B33ALG 2011/08 Prioritní fronta pomocí binární haldy – vlož prvek Vkládáme A B A A E E B U T U T M J M J X O R K X O R K Pravidlo haldy je stále porušeno, vyměň vkládaný prvek s jeho rodičem. Pravidlo haldy je zachováno, vkládaný prvek našel své místo v haldě. 43
Binární halda – vlož prvek, efektivněji A4B33ALG 2011/08 Binární halda – vlož prvek, efektivněji Vlož A Vlož A B A J 3. B>A E B E 2. J>A U T M K U T 1. K>A M J X O R X O R K Vkládaný prvek na konec haldy nevkládej. Napřed zjisti, kam patří, ostatní (větší) prvky posuň o patro dolů ... ... a teprve nakonec vlož prvek na jeho místo. 44
Binární halda – vlož prvek Binární halda – Složitost operace insert A4B33ALG 2011/08 Binární halda – vlož prvek // array: a[1]...a[n] !!!!!! int insert( Item [] a, int x, int bottom ){ int j = ++bottom; // expand the heap int i = j/2; // parent index while( (i > 0) && (a[i] > x) ){ a[j] = a[i]; // move elem down the heap j = i; i /= 2; // move indices up the heap } a[i] = x; // put inserted elem to its place return bottom; Binární halda – Složitost operace insert Vkládání představuje průchod vyváženým stromem s n prvky od listu nejvýše ke kořeni, složitost operace Insert je tedy O(log2(n)). 45