Computer Science 241
Sorting Methods

 /* The first two methods are a selection sort and a bubble sort.  Both are exchange sorts; they work by exchanging elements in the array. */

public void selectionSort ()
{
      int small, locSmall;

      for (int pass = 0; pass < listSize -1; pass ++)
     {
           small = list [pass];
           locSmall = pass;
           for (int count = pass + 1; count < listSize; count ++)
          {
                if (list [count] < small)
               {
                     small = list [count];
                     locSmall = count;
                }
           }
           list [locSmall] = list [pass];
           list [pass] = small;
      }
 } // method selectionSort
 
 public void bubbleSort ()
 {
      int temp;
      boolean success;
 
      do
     {
           success = true;
           for (int count = 0; count < listSize-1; count ++)
           {
                if (list [count] > list [count+1])
                {
                     temp = list [count];
                     list [count] = list [count+1];
                     list [count+1] = temp;
                     success = false;
                }
           }
      } while (!success);
 } // method bubbleSort

./* MergeSortClass contains a merge sort method that can be used to sort data in a linked list.  It uses two private methods, one to find the middle of the list and the other to merge two partial lists to create a full list. */

 /* mergeLists has as parameters the list heads of the two lists to be merged.  It changes the links on the two lists in order to make them into a single sorted list. */

 private Node mergeLists (Node first, Node second)
 {
      Node head, tail;
      if (second == null) // The second list is empty; return the first list.
           head = first;
      else if (first == null) // The first list is empty; return the second list.
                   head = second;
      else // Neither list is empty, so set the head and tail to the smaller list head.
     {
           if (first.getId ().compareTo (second.getId ()) < 0)
          {
                head = first;
                tail = first;
                first = first.getNext ();
           } // if
           else
           {
                head = second;
                tail = second;
                second = second.getNext ();
           } // else
           while ((first != null) && (second != null)) // Merge the two lists until one becomes empty.
           {
                if (first.getId ().compareTo (second.getId ()) < 0)
                {
                     tail.setNext (first);
                     tail = first;
                     first = first.getNext ();
                } // if
                else
                {
                     tail.setNext (second);
                     tail = second;
                     second = second.getNext ();
                } // else
           } // while
           if (first == null) // If the first list is finished, attach the rest of the second list.
                tail.setNext (second);
           else // Attach the remainder of the first list.
                tail.setNext (first);
      } // else
      return head; // head points to the beginning of the combined lists.
 } // method merge
 
 /* The method, doubleTime, sends the second pointer through the list twice as fast as the first.  When the second one is null, it moves it to the node immediately following the first node and then sets the next field of the first node to null.  This breaks the list into two lists.  These are either the same size if the original list had an even number of nodes.  Otherwise the first list has one more node than the second. */

 private Node doubleTime (Node head)
 {
      Node first = head, second;
      if ((first != null) && (first.getNext () != null)) // The list has at least two nodes.
     {
           second = first.getNext (); // This puts second one node ahead of first to begin with.
           while (second != null)
           {
                second = second.getNext (); // This puts second either at the next node or null.
                if (second != null)
                {
                     first = first.getNext (); // If second did not become null, first is advanced.
                     second = second.getNext (); // Second is kept two ahead of first with this.
                }
           }
           second = first.getNext ();
           first.setNext (null);
           return second;
      }
      else // Either the original list was empty or had just one node.
           return null;
 } // method doubleTime
 
 /* The mergeSort method uses recursion to successively divide the lists into halves.  When the lists consist of single nodes, they are then merged two at a time to create the final sorted list. */

 public Node mergeSort (Node head)
 {
      if ((head != null) && (head.getNext () != null)) // The list contains at least two nodes.
     {
           Node first = head;
           Node second = doubleTime (head); // Find the middle of the list and break the list into two.
           first = mergeSort (first);
           second = mergeSort (second);
           head = mergeLists (first, second);
      }
      return head;
 } // method mergeSort

/*quicksort is a recursive method that sorts a list by first finding the correct place for each item.  When an item has been correctly located, all items less than it are located above it, and all greater are below it.  Then quicksort is called recursively to sort the lists formed by the remaining items.*/
public void quicksort (int low, int high);
{
    int pivot, front, rear ;

    if (low < high)  // If low >= high, then the list is already sorted.
    {
        //The contents of list [low] are saved in pivot, so list [low] can be reused.
           pivot = list [low];
        /*Front is a pointer which moves up the list from low to high, while rear moves down the list from high to low.*/
           front = low;
           rear = high + 1;
           while (front < rear)  //Move pointers until front crosses over rear.
           {
                do  // Decrease rear until it points to a value less than pivot.
                {      rear = rear - 1;
                 } while ((front != rear) && (list [rear] >= pivot));
               if (front < rear)  // We are not yet done and must move front.
               {
                     /* Store list [rear] in list [front].  This will be free since list [low] has been saved in pivot */
                     list [front] = list [rear];
                    do
                    {     //Increase front until it points to a value greater than pivot.
                          front = front + 1;
                    } while  ((front != rear) && (list [front] <= pivot));
                    if (front < rear)  //We are still not done.
                        /* Store list [front] in list [rear].  List [rear] was previously saved in the former list [front].*/
                        list [rear] = list [front];
                } // if
            } // now front = rear. // Front points to the permanent location for pivot.
        } // while
        // Now sort the lists on either side of pivot.
        list [front] = pivot;
        quicksort (list, low, front-1);
        quicksort (list, rear+1, high);
        } // if (low < high)
} // method quicksort