快速排序

代码

package qp.a1;

import java.util.Arrays;
// 最优时间复杂度:nlg(n)
// 最差时间复杂度:n^2
// 平均时间复杂度:1.38nlg(n)
public class 快速排序
{
    public static void main(String[] args)
    {
        int[] disorderedArr = { 14, 3, 6, 2, 9, 5, 16, 12, 7, 9 };
        qSort(disorderedArr);
        System.out.println(Arrays.toString(disorderedArr));
    }

    private static void qSort(int[] disorderedArr)
    {
        quickSort(disorderedArr, 0, disorderedArr.length - 1);
    }

    private static void quickSort(int[] disorderedArr, int low, int high)
    {
        if (low < high)
        {
            int pivotLoc = partition(disorderedArr, low, high);
            quickSort(disorderedArr, low, pivotLoc - 1);
            quickSort(disorderedArr, pivotLoc + 1, high);
        }
    }

    private static int partition(int[] disorderedArr, int low, int high)
    {
        int pivotKey = disorderedArr[low];

        while (low < high)
        {
            while (low < high && disorderedArr[high] >= pivotKey)
                --high;
            disorderedArr[low] = disorderedArr[high];
            while (low < high && disorderedArr[low] <= pivotKey)
                ++low;
            disorderedArr[high] = disorderedArr[low];
        }

        disorderedArr[low] = pivotKey;

        return low;
    }
}

优化

1.优化枢轴(pivot)选取
显然,进行快速排序时,如果所选择的枢轴处于序列的较中间位置,排序的性能就会更好一些。因此,可以通过优化枢轴的选取来提高排序性能。
据此就有了三数取中法,即取出三个数,把其中处于中间大小的数作为枢轴,这样可以保证所选取的枢轴处于整个序列的中间位置。一般选择左、中、右三处的数作为比较,代码如下:

int m = low + (high - low) / 2;
if (arr[low] > arr[high])
    swap(arr[low], arr[high]);
if (arr[m] > arr[high])
    swap(arr[m], arr[high]);
// 以上两步保证high肯定是最大的数
if (arr[m] > arr[low])
    swap(arr[m], arr[low]); // 此时,low处即为中间位置的数

2.将交换用赋值替换
这一点以上代码已经做到了,没有使用swap(arr[low], arr[high]),而是用赋值进行操作。

3.对于小规模数据,直接采用直接插入排序

4.减少递归
计算机的栈大小是有限的,如果可以减少递归,就可以减少栈空间的使用,从而提高性能。
将quickSort代码做如下修改:

private static void quickSort(int[] disorderedArr, int low, int high)
{
    int pivotLoc = 0;
    while (low < high)
    {
        pivotLoc = partition(disorderedArr, low, high);
        quickSort(disorderedArr, low, pivotLoc - 1);
        low = pivotLoc + 1;
    }
}

通过如上修改,可以减少一半的递归调用,提高性能。

你可能感兴趣的:(快速排序)