void Merge(int A[], int Astart, int Aend, int B[], int Bstart, int Bend, int C[], int Cstart) { while (1) { if (Astart>Aend && Bstart>Bend) break; if (Astart<=Aend && Bstart<=Bend) { if (A[Astart]<B[Bstart]) { C[Cstart]=A[Astart]; Cstart+=1; Astart+=1; } else { C[Cstart]=B[Bstart]; Cstart+=1; Bstart+=1; } } else if (Astart<=Aend && Bstart>Bend) { C[Cstart]=A[Astart]; Cstart+=1; Astart+=1; } else if (Astart>Aend && Bstart<=Bend) { C[Cstart]=B[Bstart]; Cstart+=1; Bstart+=1; } }Here is an equivalent version that may be a little more efficient:
void Merge(int A[], int Astart, int Aend, int B[], int Bstart, int Bend, int C[], int Cstart) { while (Astart<=Aend && Bstart<=Bend) { if (A[Astart]<B[Bstart]) { C[Cstart]=A[Astart]; Astart+=1; } else { C[Cstart]=B[Bstart]; Bstart+=1; } Cstart+=1; } while (Astart<=Aend) { C[Cstart]=A[Astart]; Astart+=1; Cstart+=1; } while (Bstart<=Bend) { C[Cstart]=B[Bstart]; Bstart+=1; Cstart+=1; } }This is an alternate version that some may prefer. They are the same in all important respects:
void Merge(int *A, int Astart, int Aend, int *B, int Bstart, int Bend, int *C, int Cstart, int Cend) { int Aptr=Astart, Bptr=Bstart, Cptr; for (Cptr=Cstart; Cptr<=Cend; Cptr+=1) { if (Aptr>Aend) { C[Cptr]=B[Bptr]; Bptr+=1; } else if (Bptr>Bend) { C[Cptr]=A[Aptr]; Aptr+=1; } else if (A[Aptr]<B[Bptr]) { C[Cptr]=A[Aptr]; Aptr+=1; } else { C[Cptr]=B[Bptr]; Bptr+=1; } } }it merges the elements A[Astart]...A[Aend] of array A (which must already be in order) with the elements B[Bstart]...B[Bend] of array B (which must also already be ordered) putting them into elements C[Cstart]...C[Cend] of array C, producing an ordered result.
C[Cstart]...C[Cend] must not overlap either A[Astart]...A[Aend] or B[Bstart]...B[Bend].
We will also need a little function that copies from one array to another. Its just used
at the end to tidy up the loose ends.
void Copy(int *A, int Astart, int Aend, int *C, int Cstart, int Cend) { int i; int num=Aend-Astart+1; for (i=0; i<num; i+=1) C[Cstart+i]=A[Astart+i]; }Now, remember the pattern behind the sorting method. Itv relies on the fact that an array with only one thing in it can not possibly be un-sorted. First it treats the whole array A from A[0] to A[N-1] as if it were N separate tiny little (pre-sorted) arrays of one element each. These one element arrays are merged with their neighbours to produce a sequence of two element arrays in B.
void MergeSort(int *A, int N, int *B) { int *T; int *orig=A; int blocksize, firstblockstart, i, lastblockend; for (blocksize=1; blocksize<N; blocksize*=2) { for (firstblockstart=0; firstblockstart+blocksize<N; firstblockstart+=2*blocksize) { int firstblockend=firstblockstart+blocksize-1; int secondblockstart=firstblockend+1; int secondblockend=secondblockstart+blocksize-1; if (secondblockend>=N) secondblockend=N-1; Merge(A,firstblockstart,firstblockend, A,secondblockstart,secondblockend, B,firstblockstart); lastblockend=secondblockend; } Copy(A,lastblockend+1,N-1, B,lastblockend+1,N-1); T=A; A=B; B=T; } if (A!=orig) Copy(A,0,N-1,orig,0,N-1); }The standard library contains a function called "mergesort", so I called this one "MergeSort" (with capitals) to avoid a clash.
int isordered(int *A, int N) { int i; for (i=0; i<N-1; i+=1) if (A[i]>A[i+1]) return 0; return 1; }A whole program to demonstrate or test MergeSort would now be trivial to construct. It would be sensible to generate an array full of random numbers, make sure that they are not (by a very unlikely but still possible chance) already sorted, sort them, and finally make sure that they are now all in order.
#include <stdio.h> #include <stdlib.h> #define N 100 void main(void) { int A[N], B[N], i; srandomdev(); /* randomises the random number generator */ for (i=0; i<N; i+=1) A[i]=random()%1000; /* make a three digit number */ printf("Before sort, random numbers "); if (isordered(A,N)) { printf("ALREADY SORTED!!\nSorry, try again.\n"); exit(1); } else printf("not sorted\n"); MergeSort(A, N, B); printf("After sort, numbers "); if (isordered(A,N)) printf("Sorted!\n"); else printf("***NOT*** sorted.\n"); }