In deze zelfstudie leert u over samenvoegsortering. Ook vindt u werkende voorbeelden van samenvoegsortering C, C ++, Java en Python.
Merge Sort is een van de meest populaire sorteeralgoritmen die is gebaseerd op het principe van Divide and Conquer-algoritme.
Hier is een probleem opgedeeld in meerdere deelproblemen. Elk deelprobleem wordt afzonderlijk opgelost. Ten slotte worden deelproblemen gecombineerd om de uiteindelijke oplossing te vormen.

Verdeel en heers strategie
Met behulp van de Divide and Conquer- techniek verdelen we een probleem in deelproblemen. Als de oplossing voor elk deelprobleem klaar is, 'combineren' we de resultaten van de deelproblemen om het hoofdprobleem op te lossen.
Stel dat we een array A moeten sorteren. Een subprobleem zou zijn om een subsectie van deze array te sorteren, beginnend bij index p en eindigend bij index r, aangeduid als A (p… r).
Delen
Als q halverwege is tussen p en r, dan kunnen we de submatrix A (p… r) splitsen in twee arrays A (p… q) en A (q + 1, r).
Veroveren
In de veroveringsstap proberen we zowel de subarrays A (p… q) als A (q + 1, r) te sorteren. Als we het basisscenario nog niet hebben bereikt, verdelen we beide subarrays opnieuw en proberen ze te sorteren.
Combineren
Wanneer de veroveringsstap de basisstap bereikt en we krijgen twee gesorteerde subarrays A (p… q) en A (q + 1, r) voor array A (p… r), combineren we de resultaten door een gesorteerde array A ( p… r) uit twee gesorteerde subarrays A (p… q) en A (q + 1, r).
Het MergeSort-algoritme
De MergeSort-functie verdeelt de array herhaaldelijk in twee helften totdat we een stadium bereiken waarin we proberen MergeSort uit te voeren op een subarray van grootte 1, dwz p == r.
Daarna komt de samenvoegfunctie in het spel en combineert deze de gesorteerde arrays tot grotere arrays totdat de hele array is samengevoegd.
MergeSort (A, p, r): als p> r retourneert q = (p + r) / 2 mergeSort (A, p, q) mergeSort (A, q + 1, r) samenvoegen (A, p, q, r )
Om een hele array te sorteren, moeten we aanroepen MergeSort(A, 0, length(A)-1)
.
Zoals te zien is in de onderstaande afbeelding, verdeelt het samenvoegsorteeralgoritme recursief de array in twee helften totdat we het basisscenario van de array met 1 element bereiken. Daarna pakt de samenvoegfunctie de gesorteerde sub-arrays op en voegt ze samen om geleidelijk de hele array te sorteren.

De samenvoegstap van samenvoegen Sorteren
Elk recursief algoritme is afhankelijk van een basisscenario en de mogelijkheid om de resultaten van basisscases te combineren. Samenvoegen is niet anders. Het belangrijkste onderdeel van het samenvoegsorteeralgoritme is, je raadt het al, samenvoegstap.
De samenvoegstap is de oplossing voor het simpele probleem van het samenvoegen van twee gesorteerde lijsten (arrays) om één grote gesorteerde lijst (array) samen te stellen.
Het algoritme houdt drie aanwijzers bij, één voor elk van de twee arrays en één voor het behouden van de huidige index van de uiteindelijk gesorteerde array.
Hebben we het einde van een van de arrays bereikt? Nee: vergelijk huidige elementen van beide arrays Kopieer kleiner element naar gesorteerde array Verplaats pointer van element met kleiner element Ja: kopieer alle resterende elementen van niet-lege array

De code schrijven voor het samenvoegalgoritme
Een merkbaar verschil tussen de samenvoegstap die we hierboven hebben beschreven en degene die we gebruiken voor samenvoegsortering, is dat we de samenvoegfunctie alleen uitvoeren op opeenvolgende sub-arrays.
Daarom hebben we alleen de array nodig, de eerste positie, de laatste index van de eerste subarray (we kunnen de eerste index van de tweede subarray berekenen) en de laatste index van de tweede subarray.
Het is onze taak om twee subarrays A (p… q) en A (q + 1… r) samen te voegen om een gesorteerde array A (p… r) te creëren. De invoer voor de functie is dus A, p, q en r
De samenvoegfunctie werkt als volgt:
- Maak kopieën van de subarrays
L ← A(p… q)
en M ← A (q + 1… r). - Maak drie pointers i, j en k
- i handhaaft de huidige index van L, beginnend bij 1
- j handhaaft de huidige index van M, beginnend bij 1
- k handhaaft de huidige index van A (p… q), beginnend bij p.
- Kies tot we het einde van L of M bereiken de grootste van de elementen uit L en M en plaats ze op de juiste positie op A (p … q)
- Als we geen elementen meer hebben in L of M, pak dan de resterende elementen op en plaats A (p … q)
In code zou dit er als volgt uitzien:
// Merge two subarrays L and M into arr void merge(int arr(), int p, int q, int r) ( // Create L ← A(p… q) and M ← A(q+1… r) int n1 = q - p + 1; int n2 = r - q; int L(n1), M(n2); for (int i = 0; i < n1; i++) L(i) = arr(p + i); for (int j = 0; j < n2; j++) M(j) = arr(q + 1 + j); // Maintain current index of sub-arrays and main array int i, j, k; i = 0; j = 0; k = p; // Until we reach either end of either L or M, pick larger among // elements L and M and place them in the correct position at A(p… r) while (i < n1 && j < n2) ( if (L(i) <= M(j)) ( arr(k) = L(i); i++; ) else ( arr(k) = M(j); j++; ) k++; ) // When we run out of elements in either L or M, // pick up the remaining elements and put in A(p… r) while (i < n1) ( arr(k) = L(i); i++; k++; ) while (j < n2) ( arr(k) = M(j); j++; k++; ) )
Merge () Functie stap voor stap uitgelegd
Er gebeurt veel in deze functie, dus laten we een voorbeeld nemen om te zien hoe dit zou werken.
Zoals gewoonlijk zegt een foto meer dan duizend woorden.

De array A (0… 5) bevat twee gesorteerde subarrays A (0… 3) en A (4… 5). Laten we eens kijken hoe de samenvoegfunctie de twee arrays zal samenvoegen.
void merge(int arr(), int p, int q, int r) ( // Here, p = 0, q = 4, r = 6 (size of array)
Stap 1: Maak dubbele kopieën van subarrays die moeten worden gesorteerd
// Create L ← A(p… q) and M ← A(q+1… r) int n1 = q - p + 1 = 3 - 0 + 1 = 4; int n2 = r - q = 5 - 3 = 2; int L(4), M(2); for (int i = 0; i < 4; i++) L(i) = arr(p + i); // L(0,1,2,3) = A(0,1,2,3) = (1,5,10,12) for (int j = 0; j < 2; j++) M(j) = arr(q + 1 + j); // M(0,1,2,3) = A(4,5) = (6,9)

Stap 2: handhaaf de huidige index van sub-arrays en hoofdarray
int i, j, k; i = 0; j = 0; k = p;

Stap 3: Kies tot we het einde van L of M bereiken de grotere uit de elementen L en M en plaats ze op de juiste positie bij A (p … r)
while (i < n1 && j < n2) ( if (L(i) <= M(j)) ( arr(k) = L(i); i++; ) else ( arr(k) = M(j); j++; ) k++; )

Stap 4: Als we geen elementen meer hebben in L of M, pak dan de resterende elementen op en plaats A (p … r)
// We exited the earlier loop because j < n2 doesn't hold while (i < n1) ( arr(k) = L(i); i++; k++; )

// We exited the earlier loop because i < n1 doesn't hold while (j < n2) ( arr(k) = M(j); j++; k++; ) )

Deze stap zou nodig zijn geweest als de maat van M groter was dan L.
Aan het einde van de samenvoegfunctie wordt de submatrix A (p… r) gesorteerd.
Python, Java en C / C ++ voorbeelden
Python Java C C ++ # MergeSort in Python def mergeSort(array): if len(array)> 1: # r is the point where the array is divided into two subarrays r = len(array)//2 L = array(:r) M = array(r:) # Sort the two halves mergeSort(L) mergeSort(M) i = j = k = 0 # Until we reach either end of either L or M, pick larger among # elements L and M and place them in the correct position at A(p… r) while i < len(L) and j < len(M): if L(i) < M(j): array(k) = L(i) i += 1 else: array(k) = M(j) j += 1 k += 1 # When we run out of elements in either L or M, # pick up the remaining elements and put in A(p… r) while i < len(L): array(k) = L(i) i += 1 k += 1 while j < len(M): array(k) = M(j) j += 1 k += 1 # Print the array def printList(array): for i in range(len(array)): print(array(i), end=" ") print() # Driver program if __name__ == '__main__': array = (6, 5, 12, 10, 9, 1) mergeSort(array) print("Sorted array is: ") printList(array)
// Merge sort in Java class MergeSort ( // Merge two subarrays L and M into arr void merge(int arr(), int p, int q, int r) ( // Create L ← A(p… q) and M ← A(q+1… r) int n1 = q - p + 1; int n2 = r - q; int L() = new int(n1); int M() = new int(n2); for (int i = 0; i < n1; i++) L(i) = arr(p + i); for (int j = 0; j < n2; j++) M(j) = arr(q + 1 + j); // Maintain current index of sub-arrays and main array int i, j, k; i = 0; j = 0; k = p; // Until we reach either end of either L or M, pick larger among // elements L and M and place them in the correct position at A(p… r) while (i < n1 && j < n2) ( if (L(i) <= M(j)) ( arr(k) = L(i); i++; ) else ( arr(k) = M(j); j++; ) k++; ) // When we run out of elements in either L or M, // pick up the remaining elements and put in A(p… r) while (i < n1) ( arr(k) = L(i); i++; k++; ) while (j < n2) ( arr(k) = M(j); j++; k++; ) ) // Divide the array into two subarrays, sort them and merge them void mergeSort(int arr(), int l, int r) ( if (l < r) ( // m is the point where the array is divided into two subarrays int m = (l + r) / 2; mergeSort(arr, l, m); mergeSort(arr, m + 1, r); // Merge the sorted subarrays merge(arr, l, m, r); ) ) // Print the array static void printArray(int arr()) ( int n = arr.length; for (int i = 0; i < n; ++i) System.out.print(arr(i) + " "); System.out.println(); ) // Driver program public static void main(String args()) ( int arr() = ( 6, 5, 12, 10, 9, 1 ); MergeSort ob = new MergeSort(); ob.mergeSort(arr, 0, arr.length - 1); System.out.println("Sorted array:"); printArray(arr); ) )
// Merge sort in C #include // Merge two subarrays L and M into arr void merge(int arr(), int p, int q, int r) ( // Create L ← A(p… q) and M ← A(q+1… r) int n1 = q - p + 1; int n2 = r - q; int L(n1), M(n2); for (int i = 0; i < n1; i++) L(i) = arr(p + i); for (int j = 0; j < n2; j++) M(j) = arr(q + 1 + j); // Maintain current index of sub-arrays and main array int i, j, k; i = 0; j = 0; k = p; // Until we reach either end of either L or M, pick larger among // elements L and M and place them in the correct position at A(p… r) while (i < n1 && j < n2) ( if (L(i) <= M(j)) ( arr(k) = L(i); i++; ) else ( arr(k) = M(j); j++; ) k++; ) // When we run out of elements in either L or M, // pick up the remaining elements and put in A(p… r) while (i < n1) ( arr(k) = L(i); i++; k++; ) while (j < n2) ( arr(k) = M(j); j++; k++; ) ) // Divide the array into two subarrays, sort them and merge them void mergeSort(int arr(), int l, int r) ( if (l < r) ( // m is the point where the array is divided into two subarrays int m = l + (r - l) / 2; mergeSort(arr, l, m); mergeSort(arr, m + 1, r); // Merge the sorted subarrays merge(arr, l, m, r); ) ) // Print the array void printArray(int arr(), int size) ( for (int i = 0; i < size; i++) printf("%d ", arr(i)); printf(""); ) // Driver program int main() ( int arr() = (6, 5, 12, 10, 9, 1); int size = sizeof(arr) / sizeof(arr(0)); mergeSort(arr, 0, size - 1); printf("Sorted array: "); printArray(arr, size); )
// Merge sort in C++ #include using namespace std; // Merge two subarrays L and M into arr void merge(int arr(), int p, int q, int r) ( // Create L ← A(p… q) and M ← A(q+1… r) int n1 = q - p + 1; int n2 = r - q; int L(n1), M(n2); for (int i = 0; i < n1; i++) L(i) = arr(p + i); for (int j = 0; j < n2; j++) M(j) = arr(q + 1 + j); // Maintain current index of sub-arrays and main array int i, j, k; i = 0; j = 0; k = p; // Until we reach either end of either L or M, pick larger among // elements L and M and place them in the correct position at A(p… r) while (i < n1 && j < n2) ( if (L(i) <= M(j)) ( arr(k) = L(i); i++; ) else ( arr(k) = M(j); j++; ) k++; ) // When we run out of elements in either L or M, // pick up the remaining elements and put in A(p… r) while (i < n1) ( arr(k) = L(i); i++; k++; ) while (j < n2) ( arr(k) = M(j); j++; k++; ) ) // Divide the array into two subarrays, sort them and merge them void mergeSort(int arr(), int l, int r) ( if (l < r) ( // m is the point where the array is divided into two subarrays int m = l + (r - l) / 2; mergeSort(arr, l, m); mergeSort(arr, m + 1, r); // Merge the sorted subarrays merge(arr, l, m, r); ) ) // Print the array void printArray(int arr(), int size) ( for (int i = 0; i < size; i++) cout << arr(i) << " "; cout << endl; ) // Driver program int main() ( int arr() = (6, 5, 12, 10, 9, 1); int size = sizeof(arr) / sizeof(arr(0)); mergeSort(arr, 0, size - 1); cout << "Sorted array: "; printArray(arr, size); return 0; )
Sorteercomplexiteit samenvoegen
Tijdscomplexiteit
Best Case Complexity: O (n * log n)
Worst Case Complexity: O (n * log n)
Gemiddelde casuscomplexiteit: O (n * log n)
Complexiteit van de ruimte
De ruimtecomplexiteit van samenvoegsortering is O (n).
Voeg sorteerapplicaties samen
- Probleem met het aantal inversies
- Externe sortering
- E-commercetoepassingen