11c. Merge sort
2021-03-14
slides.com/jod/pt_11c
Docent: Jo Devriendt
Assistent: Ann Philips
Coördinator: Joost Vennekens
voornaam.achternaam@kuleuven.be
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Merge sort
Centraal idee
- Samenvoegen (merge) van twee gesorteerde sequenties is eenvoudig
- Array van lengte 1 is automatisch gesorteerd
- Voeg samen tot array van 2, 4, 8, enz
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
[5][3][1][7][2][6][4][5]
[3 5][1 7][2 6][4 5]
[1 3 5 7][2 4 5 6]
[1 2 3 4 5 5 6 7]
Merge sort
[5 3 1 7 2 6 4 5]
[5 3 1 7] [2 6 4 5]
[5 3] [1 7] [2 6] [4 5]
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Merge sort gevisualiseerd
https://en.wikipedia.org/wiki/Merge_sort#/media/File:Merge_sort_animation2.gif
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Code
void voegSamen(int a[], int n1, int n2, int b[]);
void mergeSort(int a[], int n, int b[]);
- a bevat de elementen om te sorteren
- b is tijdelijke kopieer-array
- voegSamen voegt de gesorteerde subarrays a[0..n1] en a[n1..n2] samen tot een gesorteerde array a[0..n2]
- mergeSort splitst array in twee subarrays a[0..n/2] en a[n/2..n], sorteert ze recursief, en roept voegSamen op
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
void voegSamen(int a[],int n1,int n2,int b[]){
for (int i = 0; i < n2; ++i) {
b[i] = a[i];
}
int j = 0;
int k = n1;
for (int i = 0; i < n2; ++i) {
if(j<n1 && (k==n2 || b[j]<=b[k])){
a[i] = b[j];
++j;
} else {
a[i] = b[k];
++k;
}
}
}
Kopieer a naar b
Code
j en k zijn indexen in eerste en tweede subarray
Loop over alle indexen van a
Kopieer het kleinste nog niet gekopieerde element (b[j] of b[k]) naar a[i]
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
void mergeSort(int a[],int n,int b[]){
if (n <= 1) {
return;
}
int mid = n / 2;
mergeSort(&a[0], mid, b);
mergeSort(&a[mid], n - mid, b);
voegSamen(a, mid, n, b);
}
Triviaal geval: array is gesorteerd
Code
recursieve operoep voor a[0..mid] en a[mid..n]
Voeg gesorteerde
a[0..mid] en a[mid..n] samen
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
#define N 8
int main() {
int a[N] = {5,3,1,7,2,6,4,5};
int b[N];
mergeSort(a, N, b);
for (int i = 0; i < N; ++i) {
printf("%d ", a[i]);
}
printf("\n");
}
Code
$ ./a.out
1 2 3 4 5 5 6 7
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Analyse
- n = #elementen
- Iedere recursieve stap creëert twee +- half zo grote deelproblemen
- de recursie gaat +- stappen diep
- Op elk recursieniveau doen we dan
+- n stappen werk om, gesommeerd over alle subproblemen, de elementen samen te voegen - Total aantal operaties is altijd
[5][3][1][7][2][6][4][5]
[3 5][1 7][2 6][4 5]
[1 3 5 7][2 4 5 6]
[1 2 3 4 5 5 6 7]
[5 3 1 7 2 6 4 5]
[5 3 1 7] [2 6 4 5]
[5 3] [1 7] [2 6] [4 5]
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Analyse
- Merge sort gebruikt gegarandeerd hoogstens
stappen - Sorteren vereist minstens stappen in het algemeen
- Merge sort is optimaal!
- Basisalgoritme van veel sorteerprocedures in programmeerbibliotheken
Programmeertechnieken [B-KUL-YI0855]
De Nayer, IIW, E-ICT, 2Ba + schakel, 2020-2021
Samenvatting
- Mergesort is een verdeel en heers-algoritme dat recursief sorteert
- Heeft hoogstens stappen nodig
- Is een optimaal sorteeralgoritme
11c. Merge sort
By Jo Devriendt
11c. Merge sort
- 648