View
216
Download
1
Tags:
Embed Size (px)
Citation preview
Divide and Conquer
• Divide array into smaller ones• Recursively sort smaller arrays• Recombine smaller arrays
obtaining one final sorted array
Pesudo-Code
mergesort(int *array, int first, int last) { if (first<last) { //find midpoint mid = (first+last)/2; //sort array[first..mid] mergesort(array, first, mid); //sort array[mid+1..last] mergesort(array, mid+1, last); //merge sorted halves merge(array, first, mid, last); } //if first>=last, there is nothing to do}
Pesudo-Codemerge(int *array, int first, int mid, int last) { f1=first, l1=mid, f2=mid+1, l2=last; //invariant: temp[] is in order for (i=f1; f1<=l1&&f2<=l2; i++){ if (array[f1]<array[f2]) temp[i]=array[f1++]; else temp[i]=array[f2++]; } for (;f1<=l1;f1++,i++) temp[i]=array[f1]; for (;f2<=l2;f2++;i++) temp[i]=array[f2]; for (i=first; i<=last; i++) array[i]=temp[i];}
Pesudo-Code
mergesort(int *array, int first, int last) { if (first<last) { //find midpoint mid = (first+last)/2; //sort array[first..mid] mergesort(array, first, mid); //sort array[mid+1..last] mergesort(array, mid+1, last); //merge sorted halves merge(array, first, mid, last); } //if first>=last, there is nothing to do}
Analysis-Merge Step
• If the total number of items in two array is n:– At most n-1 comparisons– n moves from original to temp array– n moves from temp to original array– Total major operation: 3n-1
21 8 654
1 2 4 5 6 8
Analysis-Recursion
• Each call to mergesort halves the array– If n = 2^k, recursion goes log(n) levels deep– If n != 2^k, there are 1+log(n)[rounded down] levels
• Level m requires 3n-2^m operations– It is O(n)
• So mergesort is O(n*log(n))
Pesudo-Code
quicksort(int *array, int first, int last) { if (first<last) { choose a pivot item p from array[first..last]; partition the items about p //the partition is array[first..pivotIdx..last] //sort S1 quicksort(array, first, pivotIdx-1); //sort S2 quicksort(array, pivotIdx+1, last); } //if first>=last, there is nothing to do}
Choose a Pivot
• Choose a pivot at random– Put it in array[first]
• Initially all items except pivot constitute the unknown region– lastS1 = first, firstUnknown = first+1
During Partition
• Invariant for the partition algorithm– Items in S1 are less than pivot– Items in S2 are greater than or equal to pivot
• Pivot = array[first], S1[first+1..lastS1], S2[lastS1+1..firstUnknown-1], Unknown[firstUnkown..last]
Partition Pesudo-Codeint partition(int *array, int first, int last) { choose pivot and swap it with array[first]; p = array[first]; lastS1 = first; firstUnknown = first+1; //determin the regions S1 and S2 while (firstUnknown<=last){ if (array[firstUnknown]<p) move array[firstUnknown] into S1 else move array[firstUnknown] into S2 } swap array[first] with array[lastS1]; return lastS1; //lastS1 is pivot index}
Move Operations
• Move array[firstUnknown] into S1
• Only 3 operations!– Swap array[firstUnknown] with array[lastS1+1]– lastS1++, firstUnknown++;
Mergesort v.s. Quicksort
• Similar• But quicksort does its work before
recursive calls, mergesort does it after.
quicksort() { if (first<last) { prepare array quicksort(); quicksort(); }}
mergesort() { if (first<last) { mergesort(); mergesort(); tidy up array }}
Analysis-Worst Case
• If the array[1..n] is alreay sorted– Requires n-1 comparison– Decrease the size of array by 1 and
pass it to recursive calls– All together, it requires
(n-1)+…+2+1=n(n-1)/2 comparisons– O(n^2)