快排又被称为分割交换排序法,好像总会在面试或者笔试中做为考察点来考察,快排也是目前常见的一些排序算法中很不错的排序方法了(均衡考量平均时间运行较快,所以我想说最佳排序来着,不过怕被打脸)。
**快速排序关键步骤**(从左往右由小到大):
1. 取一个键值K做为参照
2. 从左到右依次查找,找到一个Ki使得Ki>K
3. 从右到左依次查找,找到一个Kj使得Kj<K
4. 若i<j则Ki与Kj交换、并继续步骤2的执行。
5. 若i>=j,则将k与Kj交换,并且以J为基准点将其分为左右俩部分,并按上述方式进行递归求解排序,直至完成。
例子:按照快排的方式将下列元素排序
28 6 40 2 63 9 58 16 47 20
第一次 K=28 i j
因为i<j,故交换Ki与Kj,然后继续比较:
28 6 20 2 63 9 58 16 47 40
i j
因为这时i<j故交换位置继续比较:
28 6 20 2 16 9 58 63 47 40
因为i>=j,故交换K与Kj,并以j为基准点分割为左右俩半:
[ 9 6 20 2 16] 28 [58 63 47 40]
这样一轮下来就达到这样的效果:以28(最开始我们的K)为基准,左边都是小于28的,右边都是大于28的。忽略俩边排序的话,28已经到达它应该到的位置上了, 所以 ,依次类推的递归,对左右俩边的部分继续这样执行,这样执行完毕就会达到排序的效果。
给出代码实现:
public class QuickSort {
private int[] array = { 28, 6, 40, 2, 63, 9, 58, 16, 47, 20 };
public static void main(String[] args) {
QuickSort quickSort = new QuickSort();
System.out.print("排序前:");
quickSort.print(quickSort.array);
quickSort.quick(quickSort.array, 0, quickSort.array.length-1);
System.out.print("排序结果:");
quickSort.print(quickSort.array);
}
private void print(int[] array) {
for(int i=0;i<array.length;i++) {
System.out.print(array[i]+ " ");
}
System.out.println();
}
private void quick(int[] arr, int left, int right) {
int left_ids;
int right_ids;
//第一个键值为arr[left]
if(left < right) {
left_ids = left + 1;
right_ids = right;
while(true) {
System.out.print("处理过程:");
for(int tmp : arr) {
System.out.print("[" + tmp + "]");
}
System.out.println();
for(int i=left+1; i<=right; i++) {
if(arr[i] >= arr[left]){
left_ids = i;
break;
}
left_ids++;
}
for (int j=right; j>=left+1;j--) {
if(arr[j] <= arr[left]) {
right_ids = j;
break;
}
right_ids--;
}
if(left_ids<right_ids) {
int tmp = arr[left_ids];
arr[left_ids] = arr[right_ids];
arr[right_ids] = tmp;
} else {
break;
}
}
if(left_ids >= right_ids) {
int tmp = arr[left];
arr[left] = arr[right_ids];
arr[right_ids] = tmp;
quick(arr, left, right_ids-1);
quick(arr, right_ids+1, right);
}
}
}
}
运行结果截图:
还有一种常见的写法如下:
public static int partition(int []array,int lo,int hi){
//固定的切分方式
int key=array[lo];
while(lo<hi){
while(array[hi]>=key&&hi>lo){//从后半部分向前扫描
hi--;
}
array[lo]=array[hi];
while(array[lo]<=key&&hi>lo){从前半部分向后扫描
lo++;
}
array[hi]=array[lo];
}
array[hi]=key;
return hi;
}
public static void sort(int[] array,int lo ,int hi){
if(lo>=hi){
return ;
}
int index=partition(array,lo,hi);
sort(array,lo,index-1);
sort(array,index+1,hi);
}