I recently had to a do an application that required me to sort a data set fast and efficiently. I opted to do a merge sort. Merge sort is a fast sorting algorithm which is always true with an average or worst case performance of O(n log n). What I really love about a merge sort is that it is a stable sorting algorithm.
After doing the sorting I realized that most people are unaware of how actually merge sort worked. Hence I decided to do this post so anyone can actually understand how merge sort worked behind the scene and give example codes using java and C of a merge sort on an integer array.
Merge Sort is a divide an concur sorting algorithm. The Array is divided repeatedly until we have only 2 arrays of only one element each. Then the elements in the two arrays are sorted and we work our way back up the hierarchy merging the arrays till we get a sorted array. You can get a very good description on the wiki site about merge sort.
If we take an array of 6 integers, say 5,12,3,3,9,18, we follow the process below
- Break the array in to two arrays -> 5,12,3 and 3,9,18
- Take each array and break it again -> 5 and 12,3
- Break the array till you have only 1 element each -> 12 and 3
- Now start sorting and merging – >3 and 12
- one layer up 3,12 and 1 -> 1,3,12
- one layer up 1,3,12 and 3,9,18 – > 1,3,3,9,12,18
- Now you have a sorted array
Let me explain this now with a Java code.
Note that I did not use any specific java syntax such as array.length to keep the code as generic as possible. The code methods are self explanatory.
class merge_sort { public int[] split_merge(int [] mainArr , int start, int end) { if ((end - start) < 2) { return mainArr; } int middle = (start + end) / 2; int[] A = new int[middle - start]; int[] B = new int[end - middle]; A = copy_array(mainArr, start, middle,A); B = copy_array(mainArr, middle, end ,B); //Recursively Call split_merge till we have an //array with 1 element A = split_merge(A,0,middle); B = split_merge(B,0 ,(end-middle)); //merge our way back one layer up always. mainArr = merge(mainArr, A, B, start, middle, end); return mainArr; } public int[] merge(int[] array, int[] A, int[] B, int start, int middle, int end) { int i = 0 , j = 0, k = 0; //Loop till end of main array and copy the sorted elements. for (k=0;k<(end-start);k++){ if ( (i < middle) && (A[i] < B[j]) ){ array[k] = A[i]; i=i+1; }else{ array[k] = B[j]; j=j+1; } } return array; } public int[] copy_array(int[] A, int start, int end, int[] B) { int i =start, j =0; while (i < end) { B[j] = A[i]; j+=1; i+=1; } return B; } public static void main(String args[]) { int mainArr[] = {2,3,5,1,6,4,10}; int length = 7; for(int i =0 ; i <mainarr.length; i++){ ="" system.out.format("unsorted="" array[%d]="%d" \n="" ",="" i="" ,="" mainarr[i]);="" }="" mainarr="new" merge_sort().split_merge(mainarr,0,length);="" for(int="" ;="" <mainarr.length;="" system.out.format("sorted="" <="" pre="">
Now let’s look at the same as implemented using C language. Again I have tried to make it language agnostic as possible.
#include <stdio.h> #include <string.h> int *merge_sort(int A[],int length); int *copy_array(int *A,int start , int end , int *B); int *split_merge(int *A, int start, int end); int *merge(int *arr, int *A, int *B, int start,int middle, int end); int* copy_array(int *A, int start, int end,int *B) { int i , j; j = 0; for ( i = start; i< end; i++){ B[j] = A[i]; j = j +1; } return B; } int *merge(int *arr , int *A, int *B, int start, int middle, int end) { int i = 0; int j = 0; int k = 0; for(k = 0; k < end ; k++){ if((i < middle) && (A[i] < B[j])){ arr[k] = A[i]; i = i +1 ; }else { arr[k] = B[j]; j = j +1; } } return arr; } int *split_merge(int *arr, int start, int end) { if((end-start) < 2) return arr; int k; int middle = (end -start) /2; int size_a = middle - start; int size_b = end - middle; int A[size_a]; int B[size_b]; int *_aptr = copy_array(arr , 0 , middle , A); int *_bptr = copy_array(arr, middle , end, B); _aptr = split_merge(_aptr,0,middle); _bptr = split_merge(_bptr,0, (end - middle)); arr = merge(arr , _aptr , _bptr , start , middle, end); return arr; } int *merge_sort(int A[], int length) { int start = 0; int end = length; //I put this to match the Java Code A = split_merge(A,start,end); return A; } int main(int argc, char argv[]) { int A[] = {100,50,200,1000,18,5300}; int length = 6; int *B; for ( i = 0;i < length ; i++){ printf("Unsorted Array[%d] : %d \n",i , A[i]); } int *aptr = merge_sort(A , length ); int i; for ( i = 0;i < length ; i++){ printf("Sorted Array[%d] : %d \n",i , aptr[i]); } return 0; }
So I hope that this will help you next time when you have to sort a data set and you will choose merge as an option to your application.