TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 6 Jonas Lindgren, Institutionen för Datavetenskap, LiU På denna föreläsning: Sortering Selectionsort, Bubblesort, Shakersort, Insertionsort Shellsort, Mergesort, Quicksort 1
Sortering - Motivering Varför? 25% av datorns CPU-cykler spenderas på sortering Vanligt att ADT innehåller sorterade datastrukturer Bra som fallstudie för algoritmanalys 2
Initiala problem Sortera ökande eller minskande? Svar: Enkelt problem, lätt att ändra algoritmen efteråt (byt ut < mot > ) Hur ska lika element hanteras? Går det bra att lika element byter plats? En stabil algoritm defineras som en som inte kommer att ha bytt inbördes plats mellan lika element efter sortering. Hur sorterar man bokstäver, djur, etc? Svar: Implementera interfacet Comparable<E>, som innehåller en compareto-metod. 3
Sorteringsstrategier Insertion sorts (hitta rätt plats för ett element) Linear insertion Shell sort... Selection sorts (hitta rätt element för en plats) Straight selection Heap sort... Exchange sorts (byt plats på element som ligger fel) Quick Sort Merge sort... 4
Selection sort Strategi: I varje iteration, sök efter det minsta elementet i den osorterade mängden, och lägg till elementet i slutet av den sorterade mängden. Naiv lösning ( rak selectionsort ) Dela upp arrayen i en sorterad och osorterad del Leta upp det minsta elementet i den osorterade delen och lägg sist i den sorterade Upprepa 5
Selection sort(2) Implementation exempel void selectionsort(int[] a){ for (int i = 0; i < a.length-1; ++i) { int x = i; for (int j = i+1; j < a.length; ++j) { if (a[j] < a[x]) { x = j; } } byt plats på a[i] och a[x]; } } n n 2 Asymptotisk (tids)komplexitet? Stabil? O(n 2 ) Nej 6
Bubblesort Jämför med närliggande element Start från höga index void bubblesort(int[] a) { for (int i = 0; i < a.length; ++i) { for (int j = a.length-1; j > i; --j){ if (a[j] < a[j-1]) { byt plats på a[j] och a[j-1]; } } } } n n 2 Asymptotisk (tids)komplexitet? Stabil? O(n 2 ) Ja 7
Shakersort Tvåvägs bubblesort Små element bubblar upp Stora element sjunker ner Fram och tillbaka Jämför med närliggande element Bubbla ner eller bubbla upp Gör om för varje element O(n) O(n) T shakersort? Stabil? O(n 2 ) Ja 8
Insertionsort Strategi: Dela upp arrayen en en sorterad och en osorterad del Lägg successivt in varje osorterat element på rätt plats i den sorterade delen. Algoritm Ta ut det första elementet i den osorterade delen Skjut på de element i den sorterade delen som är större än det uttagna ett steg uppåt Sätt in elementet på den nu tomma platsen T insertionsort? Stabil? O(n 2 ) Ja 9
Shell sort Generaliserad insertionsort Strategi: Välj ett lucktal N och låt n vara 0. 1. Markera vart (N+n):te element i listan och sortera dessa inbördes med insertion sort. 2. Öka n med ett och upprepa (1) tills n = N. 3. Minska N, låt n vara 0 och upprepa (1), (2) tills N < 1 Noteringar: Börja med ett stort N, upp till size/2 Att börja med N = 1 => Vanlig insertionsort 10
Shell sort(2) Val av lucksekvens N i Hibbards [ 1, 3, 7,..., 2 k -1 ] Knuths: [ 1, 4, 13,..., (3 k -1)/2 ] Gonnets: Dividera N med 2.2 stegvis, avrunda nedåt, se till att den sista blir 1, ex. n=100: [ 1, 4, 9, 20, 45 ] T shellsort? Stabil? Svårt, beror på lucksekvensen. Ej sämre än O(n 2 ) Nej 11
Merge Sort Strategi: Divide and conquer : Tag två sorterade delmängder och sortera ihop dessa. Algoritm: Då mängen innehåller 0 eller 1 element: Redan sorterad Annars: Dela upp mängden i två lika stora delar och sortera dessa Sortera ihop dessa två delar (en. Merge) 12
Merge Sort(2) Utnyttjar att det krävs få jämförelser att sortera små mängder Fördel: Bästafallet: linjär (om man utnyttjar naturliga följder) Vanlig optimering: Byt ut sorteringsalgoritmen när delmängden är tillräckligt liten! Komplexitet: Antal uppdelningar av arrayen Sortering på varje nivå O(log(n)) O(n) T mergesort = O(log(n)) * O(n) = O(nlog(n)) R mergesort = O(n) (O(1) möjlig men impl. ger dålig prestanda) Stabil? Ja (om sammanslagningsalgoritmen är väl vald) 13
Quick Sort Strategi: Divide and conquer : Välj ut ett element p, pivotelementet, och flytta åt sidan. Placera alla element < p till vänster i fältet, alla element > p till höger. Flytta in pivotelementet där den högra och vänstra delen möts Upprepa detta (rekursivt) på vänstra och högra delen. T quicksort = O(n 2 ) MEN Medelfallet nästan lika med bästafallet Ω(nlog(n))! Fördel: Jämför tal nära varandra. Bra när datamängden är mycket stor (för mer info, läs om cache-minnen!) 14
Quick Sort(2) Val av pivotelement Pivotelementet kan väljas godtyckligt men ju bättre val, desto jämnare uppdelning mellan höger och vänster Elementet längst till höger (ligger redan åt sidan ) Slumpa ett element (hoppas att det blir lagom ) Median av tre element (större chans att det blir lagom ) 15
Sammanfattning Kvadratiska algoritmer Selectionsort Shakersort Insertionsort Mer avancerade algoritmer Shellsort Mergesort Quicksort Enkla, långsamma Komplexa, snabba 16