Sorting in nondescending order: Given an array A[0..n-1], reorder A such that A[0] <= A[1] <= A[2] <= ... <=A[n-1]. An invariant is a property that is true at every step of an algorithm (at the beginning, after every recursive call/ iteration of a loop, at the end) Bubble sort: Main idea: go through the array, swapping adjacent elements if they are out of order, until the largest element goes to the end. Repeat this process until no swaps are made or this process has been done n-1 times, where n=arr.length invariant: After p passes through the array, the last p elements are in the proper order. public static void bubblesort(int[] arr) { boolean isSorted = false; for(int i=0; iarr[j+1]){ swap(arr,j,j+1); isSorted=false; } } } } Best case: Array is already sorted running time: O(n) time (I have to go to the array once). Worst case: Array is sorted in nonascending order. running time: n-1 + n-2 + n-3 + ... + 2 + 1 = 1 + 2 + 3 + ... + n-1 = n(n-1)/2 = O(n^2). Insertion sort: main idea: You split the array into 2 parts, a sorted subarray and an unsorted subarray, where A[0..i-1] is sorted and A[i..n-1] is unsorted. At each step, look at A[i] and put it into the sorted part of the array in its proper place by shifting down all elements > A[i]. After you do this for A[1], A[2], ..., A[n-1], the array is sorted. invariant: After pass i, A[0..i] is already sorted. public static void insertionSort(int[] arr) { for(int i=1; i=0 && element < arr[loc]) { arr[loc+1] = arr[loc]; loc--; } arr[loc+1] = element; } } Best case: Every element in the array is a constant number of spaces away from where it belongs in the sorted order. (special case: if everything is 0 spaces away = its sorted) running time: O(n) Worst case: The array is sorted in nonascending order running time: 1 + 2 + 3 + ... + n = n(n+1)/2 = O(n^2). Although bubble sort and insertion sort both take O(n^2) time, the constant factor behind the O-notation of insertion sort is much smaller than that of bubble sort in almost all cases. -------------------------------------------- Mergesort: Merging: Suppose I had 2 sorted arrays and I wanted to create one big sorted array out of them. How can I do it? 1. Create a third array whose size is the combined size of the 2 smaller arrays 2. Compare the smallest number in each array, and copy it into the third array. Repeat this until you have no numbers left. private static void merge(int[] arr, int start, int middle, int end) { //arr[start..middle-1] is already sorted //arr[middle..end-1] is already sorted //goal is to merge these 2 subarrays // and put the result into arr[start..end-1] int[] result = new int[end-start]; int index1 = start; int index2 = middle; int indexR = 0; while(index1 < middle && index2 < end) { if(arr[index1]< arr[index2]) result[indexR] = arr[index1]; index1++; }else{ result[indexR] = arr[index2]; index2++; } indexR++; } while(index1 < middle) { result[indexR] = arr[index1]; index1++; indexR++; } while(index2 < end) { result[indexR] = arr[index2]; index2++; indexR++; } for(int i=0; i=pivot on the right. Once we do that, if we sort the left and right, the array will be sorted. The way to prepare the array is by partitioning. Idea of the partition procedure I will present is as follows: The array[start..end] will be split into 3 parts: Every element in array[start..pivotIndex] is <= pivot Every element in array[pivotIndex+1..i-1] >= pivot Every element in array[i..end] is unknown. public static int partition(int[] arr, int start, int end) { Random r = new Random(); int randomIndex = r.nextInt(end-start); swap(arr, start, randomIndex); int pivot = arr[start]; int boundary = start; //at the beginning, there is one element <=pivot (pivot itself) for(int i=start+1; i 0 as n->infinity. The running time is almost always O(n log n).