Last time we consiuei two soiting methous: selection soit anu inseition soit.
Foi each iteiation:
!"#"$%&'( *'+%, SELECTS the next minimum in the unsoiteu pait anu puts it at the enu of the soiteu pait using a SWAP.
You always have to look at all the (unsoiteu) elements to finu the min.
,(*"+%&'( *'+%, INSERTS the next element in the unsoiteu pait in the appiopiiate place in the soiteu pait by SBIFTINu elements to make ioom. The iuntime uepenus on how many elements neeu to be shifteu.
,(*"+%&'( !'+%- Woist-case: 0(n^2) Aveiage: 0(n^2) Best-case: 0(n) (when the uata is alieauy soit, oi veiy neaily soiteu)
!./01.23+2%&$ !'+%*
Why was binaiy seaich so fast. Because we halveu the pioblem each iounu.
The iuea of uiviuing a pioblem into smallei pieces anu solving each piece sepaiately is a poweiful technique, especially if the smallei pieces aie about the same size. The technique is calleu BIvIBE-ANB-C0NQ0ER.
4"+5" !'+%
1. Biviue the pioblem into the fiist half anu seconu half (!"#"$%) 2. Soit each half iecuisively (&'()*%+) S. Neige the soiteu halves togethei into one soiteu list (&',-"(%)
Simplest case is when theie is u oi 1 elements.
public static void mergesort(int[] A) { // create a temporary array that merge will use int[] temp = new int[A.length]; mergesort(A, temp, 0, A.length-1]; }
// Sort elements between low and high inclusive private static void mergesort(int[] A, int[] temp, int low, int high) { if (high <= low) { return; } else { int mid = (low + high)/2; mergesort(A, temp, low, mid); mergesort(A, temp, mid+1, high); merge(A, temp, low, mid, high) } }
// Precondition: // The elements of A from low to mid inclusive) are sorted. // The elements of A from mid+1 to high (inclusive) are sorted. // Postcondition: // The elements of A from low to high inclusive) are sorted. private static void merge(int[] A, int[] temp, int low, int mid, int high) { // Copy elements to temp. for (int i = low; i <= high; i++) { temp[i] = A[i]; }
int i1 = low; // where in first half of temp int i2 = mid+1; // where in second half of temp int i = low; // where in A
// Copy back to A the smaller of the next element in first // half and the next element in the second half. while (i1 <= mid && i2 <= high) { if (temp[i1] < temp[i2]) { A[i] = temp[i1]; i1++; } else { A[i] = temp[i2]; i2++; } i++; } // Copy back any remaining elements is first half. while (i1 <= mid) [ A[i] = temp[i1]; i1++; i++; } // any remaining elements in second half are already in A } What is the iuntime of meige. 0(n)
6(2#7*&* '8 9"+5"*'+%-
At eveiy level of the call tiee we uo 0(n) woik Theie aie log n levels Total iuntime is 0(n log n)
0ses 0(n) extia space.
4"+5" &9:+';"9"(%*- You can avoiu half of the copying anu use the seconu half of A as temp. Note that if the last element (laigest) of the fiist half is smallei then the fiist element (smallest) of the seconu half, then the elements aie alieauy soiteu.
private static void fasterMerge(int[] A, int[] temp, int low, int mid, int high) { if (A[mid] < A[mid+1]) return;
// copy first half to temp for (int i = low; i <= mid; i++) { temp[i] = A[i]; }
int i1 = low; int i2 = mid+1; int i = low; while (i1 <= mid && i2 <= high) [ if (temp[i1] < A[i2]) { A[i] = temp[i1]; i1++; } else { A[i] = A[i2]; i2++; } i++; } while (i1 <= mid) [ A[i] = temp[i1]; i1++; i++; } }
Best case: 0(1) Woist case: 0(n) (but smallei constants than the simple meige)
What is the best-case iuntime foi meigesoit using fasteiNeige. Foi what input.
1.&$<*'+%
1. Pick an element of the aiiay as a ."#'/0 anu .1+/"/"'( the aiiay into elements less than the pivot, followeu by the pivot, followeu by the elements gieatei oi equal to the pivot. (!"#"$%) 2. Soit the two paititions iecuisively (&'()*%+) S. Bone (because eveiy pivot is in its final position) (&',-"(%)
Simplest case is when theie is u oi 1 elements
public static void quicksort(int[] A, int low, int high) { if (high <= low) { return; } else { int pivotIndex = partition(A, low, high); quicksort(A, low, pivotIndex - 1); quicksort(A, pivotIndex + 1, high); } }
You can use any element as a pivot. The fiist one is convenient.
Below is the loop invaiiant foi paitition. The inuex j is the inuex of the last element known to be less than the pivot. The inuex i is the inuex of the next element to put into <pivot iegion oi >= pivot iegion. Theie aie two cases:
The next element is < than the pivot. Swap it with the fiist >= pivot element, anu inciement both i anu j. The next element >= pivot. Inciement i.
In both cases the invaiiant stays the same foi the next iteiation.
What is the staiting anu enuing conuitions of the loop invaiiant.
Notice that j (oi lessInuex in the coue below) is conveniently the place wheie the pivot shoulu go as its final position.
// Precondition: low < high // Partitions array into elements < pivot, pivot, >= pivot // Returns the index of the pivots final position public static int partition(int[] a, int low, int high) { int pivot = A[low]; // first element is the pivot int lessIndex = low; // index of rightmost element < pivot
for (int i = low+1; i <= high; i++) { if (A[i] < pivot) { lessIndex++; swap(A, lessIndex, i); } } swap(A, low, lessIndex); return lessIndex; }
Paitition takes 0(n) time.
(Asiue: In the online book, Eck's gives a uiffeient veision of paitition. The invaiiant is to put the elements <= pivot in the fiont pait of the aiiay anu the elements >= pivot in the enu pait of the aiiay. The elements in between aie unknown. Repeateu finus two elements that neeu to switch siues. This appioach minimizeu the numbei of swaps neeueu to paitition the uata.)