快速排序
介绍
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤
- 从数列中挑出一个元素,称为"基准"(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
算法分析
- 算法复杂度平均情况:
O(nlogn)
- 稳定性
快速排序是一个不稳定的算法
演示
实例代码
/**
* Created by csx on 2016/7/8.
*/
public class Utils {
/**
* 交换两个数
* @param a
* @param i
* @param j
*/
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
/**
* 打印排序好的数
* @param a
*/
public static void print(int[] a) {
for (int i : a) {
System.out.print(i + "\t");
}
System.out.println();
}
}
/**
* Created by csx on 2016/7/10.
*/
public class QuitSort {
/*
* 快速排序
*/
private static void quickSort(int[] a, int q, int r) {
if(q<r){
int p=partition(a,q,r);//寻找中间元素的位置
quickSort(a,q,p-1);
quickSort(a,p+1,r);
}
}
/*
* 寻找中间元素的位置,并返回。
* 因为要想达到最优 该排序必须是无序的,所以可以进行再一步优化
*/
private static int partition(int[] a, int q, int r) {
//优化
int rand=(int) (Math.random()*(r-q));
Utils.swap(a,q,q+rand);
int i=q;
int j=r+1;
int x=a[q];
while(true){
while(a[++i]<x&&i<r);
while(a[--j]>x);
if(i>=j){
break;
}
Utils.swap(a, j, i);
}
Utils.swap(a,q,j);
return j;
}
public static void main(String[] args) {
int[] a=new int[]{2,5,1,7,8,10};
// bubbleSort_2(a);
quickSort(a,0,a.length-1);
Utils.print(a);
}
}