快速排序在实际中运用的比较多的算法之一。
快速排序和合并排序一样都是用到了分而治之的思想。
快速首先要从数组中找到一个元素(pivot),然后把数组中比这个数大的数字全部放在这个数字的左边,比他大的数字放在他的右边,然后按照这个步骤去整理pivot的左半边和右半边,到最后数组就是一个有序的状态。
快速排序的时间负责度是 n * logn ,并且是一种不稳定的排序算法。
例如 {5,5,4,3,3},在交换的过程,第一个5 和最后一个3交换,而第二个5与倒数第二个3交换,两个5的相对位置就发生了交换。
在快速排序中,pivot的选取方式有很多,例如中位数,或者直接使用数组的第一个元素。
同时在实现快速的排序过程中,对于递归的数组长度过短的还可以采用其他的排序方式,来减少递归的深度。
下面是快速排序的一种实现,pivot的选取采用了中位数的方式,选取数组,start,mid,end 三个位置的元素做比较来选取。
public class Solution {
public static void main(String arg[]) {
Solution s = new Solution();
int arr [] = {11,-1,99,56,-89,56,78,110,8,9,55,-7,69,-55,203,981};
s.quickSort(arr, 0, arr.length - 1);
for(int i : arr) {
System.out.print(i + " ");
}
}
public void quickSort(int arr[],int start,int end){
if(start >= end) {
return;
}
int pivot = getPivot(arr,start,end);
int i = start;
int j = end - 2;
while(i < j) {
while(arr[i] < pivot) {
i++;
}
while(arr[j] > pivot) {
j--;
}
if(i >= j) {
swap(arr,i,end - 1);
break;
} else {
swap(arr,i,j);
}
}
System.out.print("Pivot : " + String.format("%4d", pivot) + " ");
for(int e : arr) {
System.out.print(e + " ");
}
System.out.println();
quickSort(arr, start, i - 1);
quickSort(arr,i + 1,end);
}
public int getPivot(int arr[],int start, int end) {
int mid = (start + end) >> 1;
if(arr[mid] < arr[start]) {
swap(arr,mid,start);
}
if(arr[end] < arr[mid]) {
swap(arr,mid,end);
}
if(arr[end] < arr[start]) {
swap(arr,start,end);
}
swap(arr,mid,end - 1);
return arr[end - 1];
}
private static void swap(int[] arr, int m, int n) {
int i = arr[m];
arr[m] = arr[n];
arr[n] = i;
}
}
每一次递归调用之后,对于我们选择的pivot来说,比其小的元素都在其左边,比他大的元素都在他的右边。