Sort
by Isai Damier, Android Engineer @ Google

/***************************************************************************
 * Author: Isai Damier
 * Title: Singly Linked List
 * Project: geekviewpoint
 * Package: datastructure
 *
 * Description: A LinkedList is a data structure that allows access
 *   to a collection of data using pointers/references. While an
 *   array can also be defined as above, LinkedLists and arrays differ
 *   in how they are stored in memory and in the operations they
 *   allow. Unlike an array that must be stored in a block of memory,
 *   the nodes of a LinkedList can be stored anywhere because each
 *   node has a reference to the node that succeeds it. Because the
 *   nodes are stored so loosely, inserting nodes into a LinkedList
 *   is easy; whereas in an array, all the succeeding elements must
 *   be shifted. Of course, insertion also means changing the size of
 *   the array, which means creating the entire array anew.
 *
 *   Perhaps the greatest beauty of LinkedList is that it allows
 *   accessing an entire sequence of nodes using only one variable:
 *   a reference to the first node in the sequence.
 *
 *   Countless operations can be performed on LinkedLists. Following
 *   are a few, ranging from the common to the very interesting.
 **************************************************************************/ 
 public class SinglyLinkedList {

  Node head = null;
  Node tail = null;

 /*****************************************************************
   * Time Complexity of Solution:
   *   O(n*log n).
   *
   * Description: Sort the elements in this linked list in ascending
   *   order.
   *
   * Technical Details: Sorting a LinkedList in place is very costly:
   *   in the order of O(n^2 * log(n)) with a good algorithm.
   *   Therefore it makes sense to create an array from the list,
   *   sort the array, and then empty the array into the list by
   *   index. It's kind of like: unbutton a shirt; move the buttons
   *   around; then button the shirt anew. (I think it's a good analogy.)
   *****************************************************************/
  public void sort() {
    if (2 > this.size()) {
      return;
    }

    int[] A = new int[this.size()];
    //unfasten the buttons (i.e. unbutton the shirt)
    int x = 0;
    for (Node t = head; null != t; t = t.next) {
      A[x++] = t.data;//list fills array
    }    //sort the buttons
    mergesort(A, 0, A.length - 1);
    //refasten the buttons (i.e. button the shirt anew)
    x = 0;
    for (Node t = head; null != t; t = t.next) {
      t.data = A[x++];//array fills list
    }
  }

  private void mergesort(int[] input, int first, int last) {
    //break array into smaller structurally identical pieces
    int mid = (first + last) / 2;
    if (first < last) {
      mergesort(input, first, mid);
      mergesort(input, mid + 1, last);
    }
    //merge sorted pieces to get solution to original array
    int a = 0, f = first, l = mid + 1;
    int[] tmp = new int[last - first + 1];

    while (f <= mid && l <= last) {
      tmp[a++] = input[f] < input[l] ? input[f++] : input[l++];
    }
    while (f <= mid) {
      tmp[a++] = input[f++];
    }
    while (l <= last) {
      tmp[a++] = input[l++];
    }
    a = 0;
    while (first <= last) {
      input[first++] = tmp[a++];
    }
  }
}
public class SinglyLinkedListTest {

  /**
   * Test of sort method, of class SinglyLinkedList.
   */
  @Test
  public void testSort() {
    System.out.println("sort");
    int[] input = {9, 4, 5, 2, 1, 12, 6, 7, 4, 8, 3, 0, 16, 19, 11};
    SinglyLinkedList linkedList = new SinglyLinkedList();
    for (int i = 0; i < input.length; i++) {
      linkedList.addToTail(input[i]);
    }
    assertTrue(Arrays.equals(input, linkedList.toArray()));
    Arrays.sort(input);
    assertFalse(Arrays.equals(input, linkedList.toArray()));
    linkedList.sort();
    assertTrue(Arrays.equals(input, linkedList.toArray()));
  }
}