【算法描述】
- 从待排序的序列中选取一个元素(通常选第一个)记为temp,小于temp的元素把它移到K的前面,大于temp的元素移到K的后边
- K把这个序列分割成了两部分,然后分别再对这两个序列进行同步骤一的操作
- 重复步骤二,直到子序列长度不大于1,这时整个序列便是有序的了
public class Sort {
public static int quickSort(int[] r, int low, int high) {
int temp = r[low]; // 根据temp划分,此时r[low]相当于是空的
while (low < high) {
/* 从右向左找小于temp的记录 */
while (low < high && r[high] >= temp) {
high--;
}
/* 找到后,放到空单元r[low],那么r[high]就是空的了 */
if (low < high) {
r[low] = r[high];
low++;
}
/* 从左向右找大于temp的记录 */
while (low < high && r[low] < temp) {
low++;
}
/* 找到后放入空单元r[high] */
if (low < high) {
r[high] = r[low];
high--;
}
}
r[low] = temp;
return low;
}
public static void sort(int[] r, int low, int high) {
if (low < high) {
int pos = quickSort(r, low, high);
sort(r, low, pos - 1);
sort(r, pos + 1, high);
}
}
public static void main(String[] args) {
int[] r = { 48, 62, 35, 77, 55, 14, 35, 98 };
sort(r, 0, r.length - 1);
System.out.println(Arrays.toString(r));
}
}
【算法分析】
最好情况是每趟将序列一分两半,每个序列的大小相同,这时的时间复杂度是O(nlog2(n))。最坏的情况是已经排好序了,第一个元素定在原位置,左边序列为空,右边有n-1个元素,第二个元素再定到原位置,右边有n-2个元素,依次类推,时间复杂度为O(n^2)。平均情况下,空间复杂度为O(nlog2(n))。快速排序是不稳定的排序方法。
【算法优化】
由最差的时间复杂度我们可以知道,是因为我们每次选第一个元素为作为划分的标准,致使比较的次数增多。那么如果我们尽量选取序列中间值最为划分元素,比较的次数就会减少。三元素取中间值是常用方法,下面简单写一下
/*下面的两步保证了r[high]是最大的*/
int mid=low+(high-low)/2;
if(r[mid]>r[high]){
swap(r[mid],r[high]);
}
if(r[low]>r[high]){
swap(r[low],r[high]);
}
/*接下来只用比较r[low]和r[mid],保证r[mid]是中间元素*/
if(r[mid]<r[low]){
swap(r[mid],r[low]);
}
int temp=r[mid];