快速排序的基本思想是,以记录中某一个元素a为基准,使得一趟排序后的结果满足:元素a之后记录的关键字均不小于记录a,同时使其之前元素的关键字均不大于记录a。一趟快速排序后,元素a把待排序序列分为两个部分,这时只需要对前后两个部分再用相同的方法进行排序便可。
public class QuickSort {
public static void main(String[] args) {
int[ ] arr = new int[ ]{
4, 5, 1, 6, 2, 7, 3, 8
};
//快速排序
quickSort( arr, 0, arr.length - 1 );
//输出
for( int num : arr ){
System.out.print( num + " ");
}
}
//快速排序
public static void quickSort( int[ ] arr, int start, int end ){
if( start < end ){
//确定基准位置
int index = partition( arr, start, end );
//对前半部分进行快速排序
quickSort( arr, start, index - 1 );
//对后半部分进行快速排序
quickSort( arr, index + 1, end );
}
}
//一趟快速排序
public static int partition( int[ ] arr, int start, int end ){
//选择基准位置
Random random = new Random();
int index = start + random.nextInt( end - start );
int priov = arr[ index ]; //基准位置的数值
//将基准位置的数放到最右边
swap( arr, index, end );
//排序
int store_index = start; //记录已经排好的小于基准的数
for( int i = start; i < end; i++ ){
if( arr[ i ] < priov ){
swap( arr, i, store_index );
store_index++;
}
}
//将基准放回该在的位置
swap( arr, store_index, end );
//返回基准所在位置
return store_index;
}
//交换数组中的两个数
public static void swap( int[ ] arr, int a, int b ){
int temp = arr[ a ];
arr[ a ] = arr[ b ];
arr[ b ] = temp;
}
}
快速排序所需时间的平均值为 O ( n l o g n ) O(nlogn) O(nlogn),这是目前内部排序方法中所能达到的最好平均时间复杂度。但是,如果初始待排序序列的关键字有序或基本有序时,快速排序将蜕变为冒泡排序,其时间复杂度为 O ( n 2 ) O(n^{2}) O(n2) 。