C Program to Implement Merge Sort Algorithm

«
»
Problem Description

Write a C program to perform a merge sort using recursion and function.

What is Merge Sort?

Merge Sort is a divide and conquer-based sorting algorithm. In this sorting algorithm the unsorted array keeps on dividing into two halves until the array is either empty or contains only one element, which is the base case of Merge Sort, and then the halves are combined/Merged in sorted order producing a sorted array. It is one of the most popular and efficient sorting techniques.

Problem Solution

Example:

If the input array is {7, 2, 3, 10, 1, 0, 6, 9}

the expected output array will have data as {0, 1, 2, 3, 6, 7, 9, 10}

Complete Approach of Merge Sort:

Consider an unsorted array as shown in the figure.

advertisement
advertisement

Merge Sort Example

Merge Sort Algorithm
Start
1. Declare Array, left, right and mid variables
2. Find mid by formula mid = (left+right)/2
3. Call MergeSort for the left to mid
4. Call MergeSort for mid+1 to right
5. Continue step 2, 3, and 4 while the left is less than the right
6. Then Call the Merge function
End

There are several ways to write an merge sort program in C language. Let’s discuss all the ways in detail.

Participate in C Programming Certification Contest of the Month Now!
Method 1: (Using Recursion and Function)

In this method, we use recursion and function to sort an array of numbers using the merge sort algorithm.

Program/Source Code

Here is the source code of the C program to sort an array of integers using Merge Sort Algorithm. The C program is successfully compiled and run on a Linux system. The program output is also shown below.

  1. /*
  2.  * C Program to Perform Merge Sort using Recursion and Functions
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. // merge function
  9. void Merge(int arr[], int left, int mid, int right)
  10. {
  11.     int i, j, k;
  12.     int size1 = mid - left + 1;
  13.     int size2 = right - mid;
  14.  
  15.     // created temporary array
  16.     int Left[size1], Right[size2];
  17.  
  18.     // copying the data from arr to temporary array
  19.     for (i = 0; i < size1; i++)
  20.         Left[i] = arr[left + i];
  21.  
  22.     for (j = 0; j < size2; j++)
  23.         Right[j] = arr[mid + 1 + j];
  24.  
  25.     // merging of the array
  26.     i = 0;	// intital index of first subarray
  27.     j = 0;	// inital index of second subarray
  28.     k = left; // initial index of parent array
  29.     while (i < size1 && j < size2)
  30.     {
  31.         if (Left[i] <= Right[j])
  32.         {
  33.             arr[k] = Left[i];
  34.             i++;
  35.         }
  36.         else
  37.         {
  38.             arr[k] = Right[j];
  39.             j++;
  40.         }
  41.         k++;
  42.     }
  43.  
  44.     // copying the elements from Left[], if any
  45.     while (i < size1)
  46.     {
  47.         arr[k] = Left[i];
  48.         i++;
  49.         k++;
  50.     }
  51.  
  52.     // copying the elements from Right[], if any
  53.     while (j < size2)
  54.     {
  55.         arr[k] = Right[j];
  56.         j++;
  57.         k++;
  58.     }
  59. }
  60.  
  61. //merge sort function
  62. void Merge_Sort(int arr[], int left, int right)
  63. {
  64.     if (left < right)
  65.     {
  66.  
  67.         int mid = left + (right - left) / 2;
  68.  
  69.         // recursive calling of merge_sort
  70.         Merge_Sort(arr, left, mid);
  71.         Merge_Sort(arr, mid + 1, right);
  72.  
  73.         Merge(arr, left, mid, right);
  74.     }
  75. }
  76.  
  77. // driver code
  78. int main()
  79. {
  80.     int size;
  81.     printf("Enter the size: ");
  82.     scanf("%d", &size);
  83.  
  84.     int arr[size];
  85.     printf("Enter the elements of array: ");
  86.     for (int i = 0; i < size; i++)
  87.     {
  88.         scanf("%d", &arr[i]);
  89.     }
  90.  
  91.     Merge_Sort(arr, 0, size - 1);
  92.  
  93.     printf("The sorted array is: ");
  94.     for (int i = 0; i < size; i++)
  95.     {
  96.         printf("%d ", arr[i]);
  97.     }
  98.     printf("\n");
  99.     return 0;
  100. }
Program Explanation

1. The MergeSort function takes the value of the minimum and maximum index of the array
2. It calculates the mid by the formula (low+high)/2 and recursively calls itself for low to mid and mid+1 to high and then calls the merge function to merge the sorted array.
3. The Merge function merges the two arrays by comparing the value in each and taking the minimum value in the newly created auxiliary array.
4. At last, whichever array is non-empty its value is just copied in the auxiliary array.
5. In the Driver Program user just declare the array and takes the input and calls the Merge Sort and merge function as shown in the code and prints the sorted result using for loop.

Time Complexity: O(nlogn)
Time Complexity of Merge Sort is O(nlogn) for best, average, and worst case.

advertisement

Space Complexity: O(n)
Space Complexity of Merge Sort using an array is O(n), because Merge Sort requires an Auxiliary/temporary array for copying the elements.

Runtime Test Cases

Here’s the run time test cases for Merge sort algorithm for 3 different input cases.

Test Case 1 – Average Case: Here, the elements are entered in random order.

/* Average case */
Enter the size: 8
Enter the elements of array: 7 2 3 10 1 0 6 9
The sorted array is: 0 1 2 3 6 7 9 10

Test Case 2 – Best Case: Here, the elements are already sorted.

advertisement
/* Best case */
 
Enter the size: 5
Enter the elements of array: -7 -3 8 9 12
The sorted array is: -7 -3 8 9 12

Test Case 3 – Worst Case: Here, the elements are reverse sorted.

/* Worst case */
 
Enter the size: 4
Enter the elements of array: 84 32 3 -9
The sorted array is: -9 3 32 84

Method 2: (Using Linked List)

In this method, an integer linked list is sorted using the merge sort technique.

A linked list cannot be accessed randomly and because of this slow access time, sorting algorithms like quick sort cannot be applied to it. So we use merge sort for this purpose. It works on divide and conquer technique.

Program/Source Code

Here is the source code of the C program to sort integers using Merge Sort on linked list technique. The C program is successfully compiled and run on a Linux system. The program output is also shown below.

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. struct node
  5. {
  6.     int data;
  7.     struct node* next;
  8. };
  9.  
  10. struct node* sortedmerge(struct node* a, struct node* b);
  11. void frontbacksplit(struct node* source, struct node** frontRef, struct node** backRef);
  12.  
  13.  
  14. void mergesort(struct node** headRef)
  15. {
  16.     struct node* head = *headRef;
  17.     struct node* a;
  18.     struct node* b;
  19.     if ((head == NULL) || (head -> next == NULL))
  20.     {
  21.         return;
  22.     }
  23.     frontbacksplit(head, &a, &b);
  24.     mergesort(&a);
  25.     mergesort(&b);
  26.     *headRef = sortedmerge(a, b);
  27. }
  28.  
  29. struct node* sortedmerge(struct node* a, struct node* b)
  30. {
  31.     struct node* result = NULL;
  32.  
  33.     if (a == NULL)
  34.         return(b);
  35.     else if (b == NULL)
  36.         return(a);
  37.  
  38.     if ( a-> data <= b -> data)
  39.     {
  40.         result = a;
  41.         result -> next = sortedmerge(a -> next, b);
  42.     }
  43.     else
  44.     {
  45.         result = b;
  46.         result -> next = sortedmerge(a, b -> next);
  47.     }
  48.     return(result);
  49. }
  50.  
  51. void frontbacksplit(struct node* source, struct node** frontRef, struct node** backRef)
  52. {
  53.     struct node* fast;
  54.     struct node* slow;
  55.     if (source==NULL || source->next==NULL)
  56.     {
  57.         *frontRef = source;
  58.         *backRef = NULL;
  59.     }
  60.     else
  61.     {
  62.         slow = source;
  63.         fast = source -> next;
  64.         while (fast != NULL)
  65.         {
  66.             fast = fast -> next;
  67.             if (fast != NULL)
  68.             {
  69.                 slow = slow -> next;
  70.                 fast = fast -> next;
  71.             }
  72.     }
  73.  
  74.     *frontRef = source;
  75.     *backRef = slow -> next;
  76.     slow -> next = NULL;
  77.     }
  78. }
  79.  
  80. void printlist(struct node *node)
  81. {
  82.     while(node != NULL)
  83.     {
  84.         printf("%d ", node -> data);
  85.         node = node -> next;
  86.     }
  87. }
  88.  
  89. void push(struct node** head_ref, int new_data)
  90. {
  91.     struct node* new_node = (struct node*) malloc(sizeof(struct node));
  92.     new_node -> data  = new_data;
  93.     new_node->next = (*head_ref);
  94.     (*head_ref) = new_node;
  95. }
  96. int main()
  97. {
  98.     struct node* a = NULL;
  99.     push(&a, 15);
  100.     push(&a, 10);
  101.     push(&a, 5);
  102.     push(&a, 20);
  103.     push(&a, 3);
  104.     push(&a, 26775);
  105.     mergesort(&a);
  106.     printf("\n Sorted Linked List is: \n");
  107.     printlist(a);
  108.     return 0;
  109. }
Program Explanation

1. Return if head is NULL or the Linked List has only one element in the list
2. Divide the linked list into two halves.
frontbacksplit(head, &a, &b); (a and b are two halves)
3. Sort the two halves using mergesort(&a); and mergesort(&b);
4. SortedMerge() should be used to combine the sorted a and b, and headRef should be used to update the head reference. i.e. *headRef = sortedmerge(a, b);
5. Functions are used to print and insert the nodes in the linked list.

Time Complexity: O(nlogn)
Time Complexity of Merge Sort is O(nlogn) for best, average, and worst case.

Space Complexity: O(1)
Space Complexity of Merge Sort using Linked List is O(1), as it does not uses any auxiliary space with Linked List.

Runtime Test Cases
Sorted Linked List is:
3 5 10 15 20 26775

Conclusion:

  • Merge Sort is a Stable Sorting Algorithm, that is it maintains the relative order for equal values/elements.
  • Typically Merge Sort is not considered an in-place sorting algorithm.
  • Merge Sort is used in External Sorting.
  • External Sorting is the class of sorting algorithms that can handle a massive amount of data. It is required when data does not fit in the main memory and need to be stored in secondary memory.

Drawbacks:

  • For Small datasets merge sort is slower than other algorithms such as selection or insertion sort.
  • It requires additional space of O(n).
  • Even if the array is sorted Merge Sort will run completely.

To practice programs on every topic in C, please visit “Programming Examples in C”, “Data Structures in C” and “Algorithms in C”.

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & technical discussions at Telegram SanfoundryClasses.