Related Articles
Merge Sort
Difficulty Level : Medium ● Last Updated : 25 Jun, 2021
Like QuickSor t, Merge Sor t is a Divide and Conquer algorithm. It divides the input array
into two halves, calls itself for the two halves, and then merges the two sor ted halves.
The merge() function is used for merging two halves. The merge(arr, l, m, r) is a key
process that assumes that arr[l..m] and arr[m+1..r] are sor ted and merges the two
sor ted sub-arrays into one. See the following C implementation for details.
MergeSort(arr[], l, r)
If r > l
1. Find the middle point to divide the array into two halves:
middle m = l+ (r-l)/2
2. Call mergeSort for first half:
Call mergeSort(arr, l, m)
3. Call mergeSort for second half:
Call mergeSort(arr, m+1, r)
4. Merge the two halves sorted in step 2 and 3:
Call merge(arr, l, m, r)
The following diagram from wikipedia shows the complete merge sor t process for an
example array {38, 27, 43, 3, 9, 82, 10}. If we take a closer look at the diagram, we can see
that the array is recursively divided into two halves till the size becomes 1. Once the size
becomes 1, the merge processes come into action and star t merging arrays back till the
complete array is merged.
Recommended: Please solve it on “PR ACTICE” rst, before moving on to the solution.
C++
// C++ program for Merge Sort
#include <iostream>
using namespace std;
// Merges two subarrays of array[].
// First subarray is arr[begin..mid]
// Second subarray is arr[mid+1..end]
void merge(int array[], int const left, int const mid, int const right
{
auto const subArrayOne = mid - left + 1;
auto const subArrayTwo = right - mid;
// Create temp arrays
auto *leftArray = new int[subArrayOne],
*rightArray = new int[subArrayTwo];
// Copy data to temp arrays leftArray[] and rightArray[]
for (auto i = 0; i < subArrayOne; i++)
leftArray[i] = array[left + i];
for (auto j = 0; j < subArrayTwo; j++)
rightArray[j] = array[mid + 1 + j];
auto indexOfSubArrayOne = 0, // Initial index of first sub-array
indexOfSubArrayTwo = 0; // Initial index of second sub-array
int indexOfMergedArray = left; // Initial index of merged array
// Merge the temp arrays back into array[left..right]
while (indexOfSubArrayOne < subArrayOne && indexOfSubArrayTwo < sub
if (leftArray[indexOfSubArrayOne] <= rightArray[indexOfSubArray
array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
indexOfSubArrayOne++;
}
else {
array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo]
indexOfSubArrayTwo++;
}
indexOfMergedArray++;
}
// Copy the remaining elements of
// left[], if there are any
while (indexOfSubArrayOne < subArrayOne) {
array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
indexOfSubArrayOne++;
indexOfMergedArray++;
}
// Copy the remaining elements of
// left[], if there are any
while (indexOfSubArrayTwo < subArrayTwo) {
array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
indexOfSubArrayTwo++;
indexOfMergedArray++;
}
}
// begin is for left index and end is
// right index of the sub-array
// of arr to be sorted */
void mergeSort(int array[], int const begin, int const end)
{
if (begin >= end)
return; // Returns recursivly
auto mid = begin + (end - begin) / 2;
mergeSort(array, begin, mid);
mergeSort(array, mid + 1, end);
merge(array, begin, mid, end);
}
// UTILITY FUNCTIONS
// Function to print an array
void printArray(int A[], int size)
{
for (auto i = 0; i < size; i++)
cout << A[i] << " ";
}
// Driver code
int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
auto arr_size = sizeof(arr) / sizeof(arr[0]);
cout << "Given array is \n";
printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
cout << "\nSorted array is \n";
printArray(arr, arr_size);
return 0;
}
// This code is contributed by Mayank Tyagi
// This code was revised by Joshua Estes
C
/* C program for Merge Sort */
#include <stdio.h>
#include <stdlib.h>
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
/* create temp arrays */
int L[n1], R[n2];
/* Copy data to temp arrays L[] and R[] */
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
/* Merge the temp arrays back into arr[l..r]*/
i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray
k = l; // Initial index of merged subarray
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
/* Copy the remaining elements of L[], if there
are any */
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
/* Copy the remaining elements of R[], if there
are any */
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r)
{
if (l < r) {
// Same as (l+r)/2, but avoids overflow for
// large l and h
int m = l + (r - l) / 2;
// Sort first and second halves
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
/* UTILITY FUNCTIONS */
/* Function to print an array */
void printArray(int A[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
/* Driver code */
int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int arr_size = sizeof(arr) / sizeof(arr[0]);
printf("Given array is \n");
printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
printf("\nSorted array is \n");
printArray(arr, arr_size);
return 0;
}
Java
/* Java program for Merge Sort */
class MergeSort
{
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r)
{
// Find sizes of two subarrays to be merged
int n1 = m - l + 1;
int n2 = r - m;
/* Create temp arrays */
int L[] = new int[n1];
int R[] = new int[n2];
/*Copy data to temp arrays*/
for (int i = 0; i < n1; ++i)
L[i] = arr[l + i];
for (int j = 0; j < n2; ++j)
R[j] = arr[m + 1 + j];
/* Merge the temp arrays */
// Initial indexes of first and second subarrays
int i = 0, j = 0;
// Initial index of merged subarry array
int k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
/* Copy remaining elements of L[] if any */
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
/* Copy remaining elements of R[] if any */
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// Main function that sorts arr[l..r] using
// merge()
void sort(int arr[], int l, int r)
{
if (l < r) {
// Find the middle point
int m =l+ (r-l)/2;
// Sort first and second halves
sort(arr, l, m);
sort(arr, m + 1, r);
// Merge the sorted halves
merge(arr, l, m, r);
}
}
/* A utility function to print array of size n */
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 code
public static void main(String args[])
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
System.out.println("Given Array");
printArray(arr);
MergeSort ob = new MergeSort();
ob.sort(arr, 0, arr.length - 1);
System.out.println("\nSorted array");
printArray(arr);
}
}
/* This code is contributed by Rajat Mishra */
P ython3
# Python program for implementation of MergeSort
def mergeSort(arr):
if len(arr) > 1:
# Finding the mid of the array
mid = len(arr)//2
# Dividing the array elements
L = arr[:mid]
# into 2 halves
R = arr[mid:]
# Sorting the first half
mergeSort(L)
# Sorting the second half
mergeSort(R)
i = j = k = 0
# Copy data to temp arrays L[] and R[]
while i < len(L) and j < len(R):
if L[i] < R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
# Checking if any element was left
while i < len(L):
arr[k] = L[i]
i += 1
k += 1
while j < len(R):
arr[k] = R[j]
j += 1
k += 1
# Code to print the list
def printList(arr):
for i in range(len(arr)):
print(arr[i], end=" ")
print()
# Driver Code
if __name__ == '__main__':
arr = [12, 11, 13, 5, 6, 7]
print("Given array is", end="\n")
printList(arr)
mergeSort(arr)
print("Sorted array is: ", end="\n")
printList(arr)
# This code is contributed by Mayank Khanna
C#
// C# program for Merge Sort
using System;
class MergeSort {
// Merges two subarrays of []arr.
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int[] arr, int l, int m, int r)
{
// Find sizes of two
// subarrays to be merged
int n1 = m - l + 1;
int n2 = r - m;
// Create temp arrays
int[] L = new int[n1];
int[] R = new int[n2];
int i, j;
// Copy data to temp arrays
for (i = 0; i < n1; ++i)
L[i] = arr[l + i];
for (j = 0; j < n2; ++j)
R[j] = arr[m + 1 + j];
// Merge the temp arrays
// Initial indexes of first
// and second subarrays
i = 0;
j = 0;
// Initial index of merged
// subarry array
int k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
// Copy remaining elements
// of L[] if any
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
// Copy remaining elements
// of R[] if any
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// Main function that
// sorts arr[l..r] using
// merge()
void sort(int[] arr, int l, int r)
{
if (l < r) {
// Find the middle
// point
int m = l+ (r-l)/2;
// Sort first and
// second halves
sort(arr, l, m);
sort(arr, m + 1, r);
// Merge the sorted halves
merge(arr, l, m, r);
}
}
// A utility function to
// print array of size n */
static void printArray(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n; ++i)
Console.Write(arr[i] + " ");
Console.WriteLine();
}
// Driver code
public static void Main(String[] args)
{
int[] arr = { 12, 11, 13, 5, 6, 7 };
Console.WriteLine("Given Array");
printArray(arr);
MergeSort ob = new MergeSort();
ob.sort(arr, 0, arr.Length - 1);
Console.WriteLine("\nSorted array");
printArray(arr);
}
}
// This code is contributed by Princi Singh
Javascript
<script>
// JavaScript program for Merge Sort
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
function merge(arr, l, m, r)
{
var n1 = m - l + 1;
var n2 = r - m;
// Create temp arrays
var L = new Array(n1);
var R = new Array(n2);
// Copy data to temp arrays L[] and R[]
for (var i = 0; i < n1; i++)
L[i] = arr[l + i];
for (var j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
// Merge the temp arrays back into arr[l..r]
// Initial index of first subarray
var i = 0;
// Initial index of second subarray
var j = 0;
// Initial index of merged subarray
var k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
// Copy the remaining elements of
// L[], if there are any
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
// Copy the remaining elements of
// R[], if there are any
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// l is for left index and r is
// right index of the sub-array
// of arr to be sorted */
function mergeSort(arr,l, r){
if(l>=r){
return;//returns recursively
}
var m =l+ parseInt((r-l)/2);
mergeSort(arr,l,m);
mergeSort(arr,m+1,r);
merge(arr,l,m,r);
}
// UTILITY FUNCTIONS
// Function to print an array
function printArray( A, size)
{
for (var i = 0; i < size; i++)
document.write( A[i] + " ");
}
var arr = [ 12, 11, 13, 5, 6, 7 ];
var arr_size = arr.length;
document.write( "Given array is <br>");
printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
document.write( "<br>Sorted array is <br>");
printArray(arr, arr_size);
// This code is contributed by SoumikMondal
</script>
Output
Given array is
12 11 13 5 6 7
Sorted array is
5 6 7 11 12 13
Time Complexity: Sor ting arrays on di erent machines. Merge Sor t is a recursive
algorithm and time complexity can be expressed as following recurrence relation.
T(n) = 2T(n/2) + θ (n)
The above recurrence can be solved either using the Recurrence Tree method or the
Master method. It falls in case II of Master Method and the solution of the recurrence is
θ (nLogn). Time complexity of Merge Sor t is θ (nLogn) in all 3 cases (worst, average and
best) as merge sor t always divides the array into two halves and takes linear time to
merge two halves.
Auxiliar y Space : O(n)
Algorithmic Paradigm: Divide and Conquer
Sor ting In Place : No in a typical implementation
Stable : Yes
Applications of Merge Sor t
1. Merge Sor t is useful for sor ting linked lists in O(nLogn) time. In the case of linked
lists, the case is di erent mainly due to the di erence in memor y allocation of arrays
and linked lists. Unlike arrays, linked list nodes may not be adjacent in memor y. Unlike
an array, in the linked list, we can inser t items in the middle in O(1) extra space and
O(1) time. Therefore, the merge operation of merge sor t can be implemented without
extra space for linked lists.
In arrays, we can do random access as elements are contiguous in memor y. Let us say
we have an integer (4-byte) array A and let the address of A[0] be x then to access
A[i], we can directly access the memor y at (x + i*4). Unlike arrays, we can not do
random access in the linked list. Quick Sor t requires a lot of this kind of access. In a
linked list to access i’th index, we have to travel each and ever y node from the head to
i’th node as we don’t have a continuous block of memor y. Therefore, the overhead
increases for quicksor t. Merge sor t accesses data sequentially and the need of
random access is low.
2. Inversion Count Problem
3. Used in External Sor ting
Drawbacks of Merge Sor t
Slower comparative to the other sor t algorithms for smaller tasks.
Merge sor t algorithm requires an additional memor y space of 0(n) for the temporar y
array.
It goes through the whole process even if the array is sor ted.
Merge Sort | GeeksforGeeks
Recent Ar ticles on Merge Sor t
Coding practice for sor ting.
Quiz on Merge Sor t
Other Sor ting Algorithms on GeeksforGeeks :
3-way Merge Sor t, Selection Sor t, Bubble Sor t, Inser tion Sor t, Merge Sor t, Heap Sor t,
QuickSor t, Radix Sor t, Counting Sor t, Bucket Sor t, ShellSor t, Comb Sor t
Please write comments if you nd anything incorrect, or you want to share more
information about the topic discussed above.
Attention reader! Don’t stop learning now. Get hold of all the impor tant DS A concepts
with the DSA Self Paced Course at a student-friendly price and become industr y ready.
To complete your preparation from learning a language to DS Algo and many more,
please refer Complete Inter view Preparation Course.
In case you wish to attend live classes with industr y exper ts, please refer DSA Live
Classes
Like 0
Next
QuickSort
RECOMMENDED ARTICLES Page : 1 2 3 4 5 6
Merge Sort with O(1) extra space merge and O(n lg n) time
01 06, Aug 18
Why Quick Sort preferred for Arrays and Merge Sort for Linked Lists?
02 16, May 15
Quick Sort vs Merge Sort
03 28, Sep 18
Merge Sort vs. Insertion Sort
04 12, Jun 20
Ar ticle Contributed By :
GeeksforGeeks
Vote for di culty
Current di culty : Medium
Easy Normal Medium Hard Expert
Improved By : ukasp, Mayank Khanna 2, pineconelam, jnjomnsn, mayanktyagi1709,
princi singh, naveenkuma150, vishalg2, akkkkk, sidhijain, SoumikMondal,
sagepup0620
Article Tags : Amazon, Boomerang Commerce, Goldman Sachs, Grofers, Microsoft, Oracle,
Paytm, Qualcomm, Snapdeal, Target Corporation, Divide and Conquer, Sorting
Practice Tags : Paytm, Amazon, Microsoft, Snapdeal, Oracle, Goldman Sachs, Qualcomm,
Boomerang Commerce, Grofers, Target Corporation, Divide and Conquer,
Sorting
Improve Article Report Issue
Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.
Load Comments
5th Floor, A-118,
Sector-136, Noida, Uttar Pradesh - 201305
feedback@geeksforgeeks.org
Company Learn
About Us Algorithms
Careers Data Structures
Privacy Policy Languages
Contact Us CS Subjects
Copyright Policy Video Tutorials
Practice Contribute
Courses Write an Article
Company-wise Write Interview Experience
Topic-wise Internships
How to begin? Videos
@geeksforgeeks , Some rights reserved