快速排序
快速排序是对冒泡排序的一种改进,采用分治策略,以减少排序过程中的比较次数。
快速排序的平均运行时间是O(NlogN)。他的最坏庆幸性能为O(N2)。
快速排序的思想就是分治递归,将原数组按照枢纽元分成左边小右边大的情况,在对分成的2个子数组在进行相同的操作,直至子数组中只有一个元素,这时,所有的数字都被成功排序。他的优先就在时间复杂度比较低。
快速排序的基本思路
-
第一趟排序,将数组按照大小策略(根据选取的枢纽元)划分为两部分**,**其中一部分的所有数据都小于另一部分的所有数据
-
通过递归算法, 再对原数组分割的两部分分别看成一个独立的数组在进行相同规则的划分,这时原数组被划分为了4份
-
这样不断划分到最后,数组就被划分为多个由一个元素或多个相同元素组成的单元,这样数组就有序了。
代码实现
private static void quickSort(int[] array) {
recQuickSort(array, 0, array.length - 1);
}
private static void recQuickSort(int[] array, int low, int high) {
if (low >= high) {
return;
} else {
int partion = partion(array, low, high);
recQuickSort(array, low, partion - 1);
recQuickSort(array, partion + 1, high);
}
}
private static int partion(int[] array, int low, int high) {
int pivot = array[low];
while (low < high) {
while (low < high && array[low] < pivot) {
low++;
}
while (low < high && array[high] > pivot) {
high--;
}
if (low < high) {
int temp = array[low];
array[low] = array[high];
array[high] = temp;
low++;
}
}
return high;
}
快速排序最“快”的地方在于左右两边能够快速同时递归排序下去,所以最优的情况是基准值刚好取在无序区的中间,这样能够最大效率地让两边排序,同时最大地减少递归划分的次数。此时的时间复杂度仅为O(NlogN)。
快速排序也有存在不足的情况,当每次划分基准值时,得到的基准值总是当前无序区域里最大或最小的那个元素,这种情况下基准值的一边为空,另一边则依然存在着很多元素(仅仅比排序前少了一个),此时时间复杂度为O(N2)。
快速排序的速度快慢关键在于基准值的选取,它决定了划分次数以及比较次数,决定了快排的效率,因此,还有一些针对于基准值选取的优化方法,例如“三数据取中法”等,能够有效优化快速排序存在的不足之处。