快速排序及分析
归并排序将数组分为两个子数组分别排序,并将有序的子数组归并使得整个数组排序;
快速排序通过一个切分元素将数组分为两个子数组,左子数组小于等于切分元素,右子数组大于等于切分元素,将这两个子数组排序也就将整个数组排序了。
public static void quickSort(int[] list){ quickSort(list,0,list.length-1); quick3WaySort(list,0,list.length-1); } public static void quickSort(int[] list,int first,int last){ if(last>first){ int pivotIndex = partition(list,first,last); quickSort(list,0,pivotIndex-1); quickSort(list,pivotIndex+1,last); } } public static int partition(int[] list,int first,int last){ int pivot = list[first]; int i = first; int j = last; while (i<j){ while (i<j&&list[i]<pivot){ i++; } while (i<j&&list[j]>pivot){ j--; } if (i<j){ int temp = list[i]; list[i]=list[j]; list[j]=temp; } } return j; }
快速排序是原地排序,不需要辅助数组,但是递归调用需要辅助栈。
快速排序最好的情况下是每次都正好将数组对半分,这样递归调用次数才是最少的。这种情况下比较次数为 CN=2CN/2+N,复杂度为 O(NlogN)。
最坏的情况下,第一次从最小的元素切分,第二次从第二小的元素切分,如此这般。因此最坏的情况下需要比较 N2/2。为了防止数组最开始就是有序的,在进行快速排序时需要随机打乱数组。