# 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. 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.

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.

```/* 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```

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”. 