快速排序
和归并排序一样,快排也使用了Divide and Conquer。不同的是,merge sort在divide部分没做什么排序,真正的工作在combine阶段的merge()方法里;而quick sort则相反,真正的工作在divide完成,而在combine阶段,没做什么.
快速排序属于内部排序,in place,
Quicksort has a couple of other differences from merge sort. Quicksort works in place. And its worst-case running time is as bad as selection sort’s and insertion sort’s: Θ(n2). But its average-case running time is as good as merge sort’s: Θ(nlgn). So why think about quicksort when merge sort is at least as good? That’s because the constant factor hidden in the big-Θ notation for quicksort is quite good. In practice, quicksort outperforms merge sort, and it significantly outperforms selection sort and insertion sort.
quick sort divide-and-conquer:
Divide: 选择数组array[low…high]任意一个元素作为pivot,以pivot为基础,比pivot小的,放左边,大的放右边。这个过程,叫做partitioning。在实际操作中,经常选择最右端的元素作为pivot。mid位pivot结束位置
Conquer: 递归排序,array[low..mid-1],所有元素小于pivot,array[mid + 1],所有元素大于pivot。注意,meger sort与binary search包含了mid,quick sort这里没有。
Combine:没做什么
递归的条件,若只有0或1个元素,即low>=high,不用排序了。所以,只有low
public class QuickSort {
public static void main(String[] args) {
int[] a = { 12, 6, 8, 3, 16, 22, 9, 14, 2, 17 };
quickSort(a);
for (int i : a) {
System.out.print(i + " ");
}
}
public static void quickSort(int[] array){
quick_Sort(array,0,array.length-1);
}
private static int[] quick_Sort(int[] array, int low, int high) {
int pivot;
if(low < high) {
pivot = partition(array,low,high);
quick_Sort(array, low,pivot);
quick_Sort(array, pivot + 1,high);
}
return array;
}
//////////////////////////////////////////////////////////////
partition()方法1,对应
quick_Sort(array, low,pivot);
quick_Sort(array, pivot + 1,high);
///////////////////////////////////////////////////////////////
private static int partition(int[] a, int low, int high) {
int pivot = a[low];
while(low < high){
while((low<high) && a[high] >= pivot){
high--;
}
swap(a, low, high);
while((low<high) && a[low] <= pivot) {
low++;
}
swap(a, low, high);
}
return low;
}
///////////////////////////////////////////////////////////
partition()方法2,linear runtime,对应;
quick_Sort(array, low,pivot - 1);
quick_Sort(array, pivot + 1,high);
/////////////////////////////////////////////////////////
private static int partition(int[] array, int low, int high) {
int q = low;
int j = low;
// Compare array[j] with array[high], for j = p, p+1,...r-1
for(j=low;j<high;j++){
if(array[j] <= array[high]){
swap(array, j, q);
q++;
}
}
swap(array, high, q);
return q;
}
private static void swap(int[] array, int low, int high) {
int temp = array[low];
array[low] = array[high];
array[high] = temp;
}
奇怪的是,用javascript实现partition()方法2,没栈溢出,java实现会。。。。。暂时没想到是什么问题
quickSort的javascript练习地址:
https://www.khanacademy.org/computing/computer-science/algorithms/quick-sort/p/challenge-implement-partition