You are on page 1of 5

EXPERIMENT 2

Aim : To implement and analyze merge sort algorithm.

Theory :
Merge sort is a sorting algorithm that uses the divide, conquer, and combine
algorithmic paradigm. Divide means partitioning the n - element array to be sorted
into two sub-arrays of n/2 elements. If A is an array containing zero or one element,
then it is already sorted. However, if there are more elements in the array, divide A
into two sub-arrays, A1 and A2 , each containing about half of the elements of A .
Conquer means sorting the two sub-arrays recursively using merge sort. Combine
means merging the two sorted sub-arrays of size n/2 to produce the sorted array of n
elements.

Algorithm :

A ← array of n elements
p ← starting index of array
r ← last index of array

MERGE_SORT (A, p, r)
{
if p < r
{
q = |_(p+r)/2_|
MERGE_SORT(A, p, q)
MERGE_SORT(A, q+1, r)
MERGE (A, p, q, r)
}
}

q ← midpoint of array

MERGE (A, p, q, r)
{
n1←q-p+1
n2←r-q
create arrays L[1....n1 + 1] and R[1....n2 + 1]
for i ← 1 to n1
L[i] ← A[p + i - 1]

for j ← 1 to n2
R[j] ← A[q + j]

L[n1 + 1] ← ∞
R[n2 + 1] ← ∞

i←1
j←1

for k ← p to r
if L[i] ≤ R[j]
A[k] ← L[i]
i←i+1
else A[k] ← R[j]
j←j+1
}

Implementation Code :

#include<stdio.h>
#include<stdlib.h>

void mergesort(int *arr, int p, int r);


void merge(int *arr, int p, int q, int r);
static int comp, count;

int main()
{
int *arr, i, n;
printf("Enter the size of array : ");
scanf("%d", &n);

arr = (int*)malloc(sizeof(int)*n);

for(i = 0; i<n; i++)


{
arr[i] = rand()%1000;
printf("%d ", arr[i]);
}
printf("\n\n");

mergesort(arr, 0, n-1);

printf("\n\nThe sorted array is: \n");


for(i = 0; i<n; i++)
printf("%d ", arr[i]);
printf("\n\nNumber of comparisons required are : %d\n", comp);
}
void mergesort(int *arr, int p, int r)
{
if(p < r)
{
int q;
q = (p+r)/2;
mergesort(arr, p, q);
mergesort(arr, q+1, r);
merge(arr, p, q, r);
}
}

void merge(int *arr, int p, int q, int r)


{
int n1, n2, *left, *right;
int i, j, k;

n1 = q – p + 1;
n2 = r - q;

left = (int*)malloc(sizeof(int)*(n1+1));
right = (int*)malloc(sizeof(int)*(n2+1));

left[n1] = 9999;
right[n2] = 9999;

printf("\n\n%d merge\n", ++count);

for(i=0; i<n1; i++)


{
left[i] = arr[p+i];
}

for(j = 0; j<n2; j++)


{
right[j] = arr[q+j+1];
}

i = 0;
j = 0;

for(k = p; k<=r; k++)


{
if(left[i] < right[j])
{
arr[k] = left[i];
i++;
}
else
{
arr[k] = right[j];
j++;
}
comp++;
}
}

Output :

Observation Table :

Input Size (n) Number of comparisons n*log2(n)


50 286 282.1928
100 672 664.3856
500 4488 4482.8921
1000 9976 9965.7843
2500 28404 28219.2809
5000 61608 61438.5619
7500 96808 96545.0616
10000 133616 132877.1238
The first column of the table represents the size of the input array , the second column
represents the number of comparisons required to sort the elements of the array using
the merge sort algorithm. Third column shows the standard rate of growth of merge
sort algorithm with respect to input size of the array.

Graph :

Merge Sort
160000

140000
No. of comaprisons & n*log2(n)

120000

100000

80000 Number of comparisons


n*log2(n)
60000

40000

20000

0
50 100 500 1000 2500 5000 7500 10000
Input Size (n)

The graph represents the worst-case time complexity of Merge sort. The red line
represents the no. of comparisons for different values of input size n and the blue line
represents the value of nlog2(n) gives an upper bound on the complexity. Thus, the
worst-case complexity of Merge Sort is O(nlog(n)).

Conclusion :

 The divide step takes constant time i.e. O(1) as it computes the midpoint q of
the indices p and r.
 The conquer step to recursively sort two subarrays of approximately n/2
elements each takes O(log(n)) time.
 The combine step merges a total of n elemnts and takes O(n) time.

Therefore, time complexity of Merge Sort in all three cases i.e best case, avergae case
and worst case i O(nlog(n)) as merge sort always divides the array into two halves
and take linear time to merge two halves. It needs an additional space of O(n) for the
temporary arrays.

You might also like