42C. Implementation of Merge Sort for Linked Lists

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));
}