Sortering och Länkade Listor
- Varför ? Några algoritmer, kap 8
-En annan typ av datastruktur, Länkad
lista, kap 17.
Varför är sortering viktigt? Rekursiv binär sökning
public static int binarySearch(Comparable [ ] a, Comparable x)
{
return binarySearch(a,x,0,a.length-1) ;
}
private static int binarySearch(Comparable [ ] a, Comparable x,
int low, int hight){
if(low>hight)
return -1;
int mid=low+hight/2
else {
if(a[mid].compareTo(x)<0)
return binarySearch(a,x,mid+1,hight); // här anropar metod sig själv med högra halvan
else if(a[mid].compareTo(x)>0
return binarySearch(a,x,low,mid-1); // här anropar metod sig själv med vänstra halvan
else
return mid;
}
Varför är sortering viktigt ? En annan exempel.
public static boolean duplicates( int [] a)
{
for(int i=0;i<a.lenght;i++)
for(int j=i+1;j<a.length; j++)
if(a[i]==a[j]);
return true ;
return false;
}
Om en samling data är sorterad, effektiviteten av alla
algoritmer på respektive datan ökar betydligt.
Kvadratiska O(n^2) sorteringar
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
Ex.tiden O( )
a[j]=a[j-1];
Om arrayen är redan
}
sorterad?
a[j]=temp;
}
Ex.tiden O( )
}
insertionSort
8
4
2
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=4
8
4
2
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=4
8
8
2
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=4
8
8
2
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=4
4
8
2
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=2
4
8
2
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=2
4
8
8
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=2
4
8
8
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=2
4
4
8
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=2
4
4
8
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=2
2
4
8
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
2
4
8
7
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=7
2
4
8
8
1
9
3
5
public static void insertionSort(int [] a)
{
for(int p=1;p<a.length;p++){
int temp=a[p];
int j=p;
for (; j>0 && temp<a[j-1] ; j--){
a[j]=a[j-1];
}
a[j]=temp;
}
}
6
temp=7
2
4
7
8
1
9
3
5
6
insertionSort()- speciellt fall
1
2
3
4
5
6
7
8
8
Vad blir exekveringstiden när arrayen är sorterad?
Tidskomplexitet (värstafall): 1 + 2 + 3 + …. + n-1 = n(n-1)/2 = O(n2)
Subkvadratiska sorteringsalgoritmer
använder divade & conquer - strategi
Merge Sort O( NlogN)
Dela arrayen i två halvor, sortera halvorna och sedan
sätter ihopp halvorna ( merge) i en sorterad array
Quick Sort O(NlogN)
Dela arrayen i två delar genom att välja ett element i
arrayen som pivot. Element som är mindre en
pivoten fyttas till enda delen, element som är större
till den andra.Sortera delarna.
Divade & Conquer - strategi


Att dela ett problem i två mindre
subproblem som kan lösas rekursivt
Att sätta ihop lösningen till
subproblemen för att lösa original
problemet.
MergeSort -algoritmen
8
4
8
4
8
4
8
2
2
1
9
7
2
4
7
2
3
1
7
1
7
1
9
9
9
6
3
6
3
6
3
6
MergeSort
8
4
4
8
2
1
4
2
2
7
7
7
8
1
9
1
1
3
9
3
6
3
6
6
9
MergeSort
8
4
4
8
2
1
2
2
4
2
7
7
7
8
1
9
1
1
3
9
3
6
3
6
6
9
MergeSort
8
4
4
8
2
1
2
2
4
2
7
7
7
8
1
9
1
1
3
9
3
6
3
6
6
9
MergeSort
8
4
4
8
2
1
2
2
4
2
7
3
7
7
8
1
9
1
1
3
9
3
6
3
6
6
9
MergeSort-algoritmen
8
4
4
8
2
1
2
2
4
2
7
3
7
7
8
1
1
1
9
3
9
3
3
6
6
6
9
Tidskomplexiteten?
7
5
9
7
3
6
9
0
0
2
3
5
2
0
2
3
4
5
6
0
2
3
4
5
6
4
4
Dela i två halvor
6
Sortera halvorna
7
9
Gör ”merge” till en temp array
7
9
Kopiera temp arrayen tillbaka
till original arrayen
Java implementation av Merge Sort
public static void mergeSort( int [] a)
{
int [] temp= new int[a.length];
mergeSort(a, temp, 0, a.length-1);
}
private static void mergeSort( int [] a, int[] temp,int first,int last)
{
if(first<last){
int center=first+last/2;
mergeSort(a,temp,first,center);
mergeSort(a,temp,center+1,last)
merge(a,temp,first,center+1,last);
}
}
Se merge () i kurslitteraturen
Quicksort





Divide and conquer algoritm med flera variationer
Bättre i medelfall än övriga algoritmer
Dålig i värsta fall, som dock kan händer nästan
aldrig
Idé: Välj ut ett element (pivot) och se till att det
hamnar på rätt plats genom att först flytta om övriga
element så att alla som är mindre än pivotelementet
hamnar till vänster och alla större hamnar till höger.
Upprepa sedan (rekursivt) på vänster och höger
delar av arrayen
QuickSort- implementationsskiss
<=pivot
pivot
>=pivot
quickSort( a,first,last)
{
if(first<last)
// välj pivot
// dela arrayen
quickSort(a,first,pivotindex-1) // sortera mindre
quickSort(a,pivotindex+1,last) // sortera större
}
Quicksort med pivot = median av tre
Antag vi skall sortera delvektorn a[low] ..a[high].
Mittplatsen mid = (low + high) / 2.
Utred storleksordningen mellan elementen a[low], a[high] och a[mid].
Byt samtidigt platser så att platsen low kommer att innehålla det minsta av
dem, mid det mittersta i storleksordning och high det största.
low mid
high
8149635270
low
mid
high
0149635278
Pivotelementet = medianen av de tre = elementet som nu
QuickSort()
8
1
4
9
Median av tre ->6
6
3
5
2
7
0
QuickSort()
8
1
4
9
0
3
5
2
7
6
QuickSort()
2
1
4
9
0
3
5
8
7
6
QuickSort()
2
1
4
5
0
3
9
8
7
6
QuickSort()
2
1
4
5
0
3
6
8
7
9
Tidskomplexiteten
1)Bästa fall (kan man visa) : Delar vektorn i lika stora
delar i varje pass.
Rekursionsformeln blir T(n) = 2T(n/2) + n vilket ger T(n)
n*log n.
2)Sämsta fall: Vektorn delas alltid i en tom del och en
del som består av alla element utom pivot.
Rekursionsformel: W(n) =
W(n-1) + n ==> W(n) = n(n-1)/2 = O(n2)