The following is an implementation of Merge Sort. It uses a little trick to avoid the inconvenience of cutting the list in half before sorting the halves. Instead, it only sorts a prefix of L of a given length, and tells its caller what the suffix after that prefix is. For example, if L has length 20, then MergeSort(L, n) returns a sorted version of the first 10 members of L and sets L to point to the remaining 10 members. Then it is up to the caller to sort those last 10 members.
If you have trouble understanding the code, do a hand simulation with a linked list diagram.
/*======================================================*
* length *
*======================================================*
* length(L) returns length list L. *
*======================================================*/
int length(ConstList L)
{
int count = 0;
for(ConstList p = L; p != NULL; p = p->tail)
{
count++;
}
return count;
}
/*======================================================*
* merge *
*======================================================*
* merge(A,B) requires that lists A and B are already *
* in nondescending order. It merges them into a single*
* list in ascending order and returns that list. *
* *
* NOTE: This function does not allocate new list cells.*
* It reorders the cells that make up lists A and B. *
* After merge(A,B), lists A and B have been destroyed *
* to make the sorted list. *
*======================================================*/
List merge(List A, List B)
{
if(A == NULL)
{
return B;
}
else if(B == NULL)
{
return A;
}
else if(A->head < B->head)
{
A->tail = merge(A->tail, B);
return A;
}
else
{
B->tail = merge(A, B->tail);
return B;
}
}
/*======================================================*
* MergeSort *
*======================================================*
* MergeSort(L,n) reorders the first n members of list *
* L into ascending order, and returns that list. It *
* sets parameter L to point to the remainder of the *
* original list L, after the first n members. *
* *
* For example, if L = [5,2,3,6,4], then *
* MergeSort(L,3) *
* returns [2,3,5] and sets L = [6,4]. *
* *
* NOTE: This function rearranges the first n list *
* list cells. It does not create new cells. *
*======================================================*/
List MergeSort(List& L, const int n)
{
if(n == 0)
{
return NULL;
}
else if(n == 1)
{
List p = L;
L = L->tail;
p->tail = NULL;
return p;
}
else
{
int m = n/2;
List A = MergeSort(L, m);
List B = MergeSort(L, n-m);
return merge(A,B);
}
}
/*======================================================*
* SortList *
*======================================================*
* SortList(L) sorts list L into ascending order by *
* rearranging the cells. *
*======================================================*/
void SortList(List& L)
{
L = MergeSort(L, length(L));
}