您的位置:首页 > 其它

快速排序

2016-03-27 22:44 363 查看

代码

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;
}
}


通过如上修改,可以减少一半的递归调用,提高性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  快速排序