public class Sorting {
  
  /**
   * Display the contents of the list.
   */
  public static void displayList(int[] list) {
    for(int i = 0; i < list.length; i++) {
      System.out.print(list[i] + " ");
    }
    System.out.println();
  }

  /**
   * Sort the items in an array in increasing
   * order.
   * 
   * Bubble sort:
   * - traverse the list comparing neighbouring
   *   elements
   * - move the smaller element into the lower
   * position
   * - repeat list.length times
   */
  public static void bubbleSort(int[] list) {
    int swaps = 0;
    int comps = 0;
    
    for(int j = 0; j < list.length; j++) {
      for(int i = 0; i < list.length - 1; i++) {
        
        // compare adjacent elements
        if(list[i] > list[i+1]) {
          
          // swap
          int temp = list[i];
          list[i] = list[i+1];
          list[i+1] = temp;
          swaps++;
        }
        comps++;
      }
    }
    displayList(list);
    
    System.out.println("Swaps: " + swaps 
                         + " Comparisons: " + comps); 
  }
  
  /* Bubble sort (improved!):
   * - stop when the list is sorted
   * - don't compare with elements that are
   * definitely in their sorted position
   */
  public static void bubbleSort2(int[] list) {
    boolean didSwap = true;
    int j = 0;
    int swaps = 0;
    int comps = 0;
    
    while(didSwap) {
      didSwap = false;
      for(int i = 0; i < list.length - 1 - j; i++) {
        
        // compare adjacent elements
        if(list[i] > list[i+1]) {
          didSwap = true;
          // swap
          int temp = list[i];
          list[i] = list[i+1];
          list[i+1] = temp;
          swaps++;
        }
        comps++;
      }
      j++;
    }
    displayList(list);
    System.out.println("Swaps: " + swaps 
                         + " Comparisons: " + comps); 

  }

  /** 
   * Insertion sort:
   * - pick an element from the unsort section of
   * the list
   * - insert it into its proper position in the
   * sorted part of the list
   * - repeat for all elements
   */
  public static void insertionSort(int[] list) {
   
    for(int i = 0; i < list.length; i++) {
      int j = i;
      
      // compare element i with the elements
      // in the sorted part of the list [0..i-1]
      // and insert it into the sorted part of the list
      while(j != 0 && list[j] < list[j-1] ){
      
        // swap element at j with element at j-1
        int temp = list[j];
        list[j] = list[j-1];
        list[j-1] = temp;
        j--;
      }
    }
  }
}

