快速排序(Quick Sort)
基本思想:
通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对着两部分记录进行排序,以达到整体有序的目的。
通俗点说就是:
在待排记录中找出一个记录,然后想办法将它放到一个位置,是得它左边的值都比他小,右边的值都比他大(正序或者倒序),把这个记录称作枢轴(pivot)。
然后对枢轴左边和右边的记录重复这个步骤,直到达到整体有序的状态。
可以先看一下快排的百度介绍
快排介绍:
优化后的快排(只有更好的没有最好的,这个也是一样。)
package algorithm; import java.util.Arrays; /** * @author wzy * @since 18-6-20 */ public class QuickSort { public static void quickSort(int a[], int low, int high) { if (low > high) return; int pivot; //在这里使用了尾递归优化,采用迭代的方法缩减虚拟机栈的深度,从而提高整体性能。 //虚拟机栈中存放的东西请自行搜索 while (low < high) { pivot = partition(a, low, high); quickSort(a,low,pivot-1); low = pivot + 1; } } /** * @param a 待排数组 * @param low 待排数组起始下标 * @param high 待排数组截止下标 * @return pivot的下标 */ private static int partition(int[] a, int low, int high) { int pivot = getPivot(a); while (low < high) { while (low < high && a[high]>=index) high--; if (low < high) a[low++] = a[high]; while (low < high && a[low] < index) low++; if (low < high) a[high--] = a[low]; } a[low] = index; return low; } /** * 由于pivot的选择直接会影响到排序的性能(递归调用的次数)。 * 所以我们如果选择的pivot越接近中间值,效果越好。 * 在这里使用“三数取中”的方法来获取pivot * * @param a 待排数组 * @return pivot */ private static int getPivot(int[] a) { //省略参数检查 int h, m; m = (h = a.length - 1) >> 1; return a[0] >= a[m] && a[0] <= a[h] ? a[0] : (a[m] >= a[0] && a[m] <= a[h] ? a[m] : a[h]); } public static void main(String[] args) { int a[] = {49, 38, 65, 97, 76, 13, 27, 49, 1, 4, 2, 5, 7, 99, 88, 77, 66}; quickSort(a, 0, a.length - 1); System.out.println(Arrays.toString(a)); } }
QuickSort
快速排序也好,其他排序也好,我现在还没了解到有十全十美的排序算法。不同的排序算法都会有自己的优点和缺点,所以我们要针对不同的情况去选择合适的算法。
快速排序的复杂度和稳定性:
平均情况:O(nlogn)
最好情况:O(nlogn)
最坏情况:O(n2)
辅助空间:O(logn)~O(n)
稳定性:不稳定