算法介绍:
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
6
|
2
|
7
|
3
|
8
|
9
|
创建变量i=0(指向第一个数据), j=5(指向最后一个数据), k=6(赋值为第一个数据的值)。
下标
|
0
|
1
|
2
| 3 |
4
|
5
|
数据
|
3
|
2
|
7
|
6
|
8
|
9
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
快速排序的示例:
(a)一趟排序的过程:
(b)排序的全过程
算法的实现:
public class QuickSort {
public static void main(String[] agrs) {
int a[] = new int[] {49, 38, 65, 97, 76, 13, 27, 36, 91};
System.out.println("排序之前:");
print(a);
System.out.println("\n开始排序:");
sort(a, 0, a.length-1);
System.out.println();
System.out.println("排序之后:");
print(a);
}
private static void sort(int[] a, int l, int r) {
if (l < r) {
int privotLoc = partition(a, l, r); //将表一分为二
sort(a, l, privotLoc - 1); //递归对左子表递归排序
sort(a, privotLoc + 1, r); //递归对右子表递归排序
}
}
// 注意: 如果把注释的代码打开,就可以去掉这行a[left] = k;
private static int partition(int[] a, int left, int right) {
int k = a[left]; //基准元素
System.out.println("left=" + left + ", right=" + right + ", k=" + k);
while (left < right) { //从表的两端交替地向中间扫描
while (left < right && a[right] >= k) --right; //从right 所指位置向前搜索,至多到left+1 位置。将比基准元素小的交换到低端
if (left < right) {
// int temp = a[left];
a[left] = a[right];
// a[right] = temp;
}
while (left < right && a[left] <= k) ++left;
if (left < right) {
// int temp = a[right];
a[right] = a[left];
// a[left] = temp;
}
}
a[left] = k; //把k填回中间位置
print(a);
return left;
}
private static void print(int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
}
结果输出:
排序之前:
49 38 65 97 76 13 27 36 91
开始排序:
left=0, right=8, k=49
36 38 27 13 49 76 97 65 91
left=0, right=3, k=36
13 27 36 38 49 76 97 65 91
left=0, right=1, k=13
13 27 36 38 49 76 97 65 91
left=5, right=8, k=76
13 27 36 38 49 65 76 97 91
left=7, right=8, k=97
13 27 36 38 49 65 76 91 97
排序之后:
13 27 36 38 49 65 76 91 97
动画演示: http://www.tyut.edu.cn/kecheng1/site01/suanfayanshi/quick_sort.asp
分析:
快速排序是通常被认为在同数量级(O(nlog2n))的排序方法中平均性能最好的。但若初始序列按关键码有序或基本有序时,快排序反而蜕化为冒泡排序。为改进之,通常以“三者取中法”来选取基准记录,即将排序区间的两个端点与中点三个记录关键码居中的调整为支点记录。快速排序是一个不稳定的排序方法。