快排简介
快速排序(quick sort) 是算法题中经常遇到的工具类算法,所谓工具类算法就是存在很多的算法或者思考题是基于相同思想进行解答的,那么这类算法被考察的概率很高,对于这类算法的思考和探究也就十分有意义!
快排也是在实践中应用非常广泛的一种排序算法,特别是在C++或对Java基本类型的排序中特别有效。
为什么说是基本类型? 这是在对比归并排序(merge sort)和快排时经常提的问题,原因在于两种排序方式各自的特点:
快速排序(quick sort)元素移动次数少,元素比较次数多;
归并排序(merge sort)元素移到次数多,元素比较次数最少。
而算法的运行时间耗费在:
1)比较元素;
2)移动元素。
所以快排更加适用于比较成本较低的基本类型,而对于耗时较长的泛型比较,例如实现comparator接口,就该考虑使用比较次数较少的归并排序了。
它的平均运行时间是 O ( N log N ) O(N \log N) O(NlogN),但是不稳定,它的最坏情形时间复杂度为 O ( N 2 ) O(N^2) O(N2),但是这种不稳地是可以通过对算法的优化避免的,接下来就讨论对算法的优化问题。
常见写法
public static void QSort(int[] a, int left, int right) {
if(left >= right) {
return;
}
//选择最左边元素为基线值
int base = a[left];
int i = left;
int j = right;
//移动元素使得基线值
while(i < j) {
//左移放前面
while(i < j && base <= a[j]) {
j--;
}
//右移
while(i < j && base >= a[i]) {
i++;
}
if(i < j) {
swap(a, i, j);
}
}
//交换base和比base小的最后一个元素的值
swap(a, left, i);
QSort(a, left, i-1);//左边递归
QSort(a, i+1, right);
}
快排是一种分治的递归算法,描述这种最常见的快排实现方式,
对数组 S S S进行排序的基本算法由下面4步组成:
- 如果 S S S中的元素个数为0或者1,则返回;
- 取 S S S中的任意元素 u u u,称为枢纽元(pivot),上面实现采用的是数组的第一个元素作为枢纽元;
- 将数组除 u u