1、从数据中选取一个值a[i]作为参考
2、以a[i] 为参考,将数据分成2部分:P1、P2,P1中的数据全部≤a[i],P2中的数据全部>a[i],数据变为{{P1}{a[i]}{P2}}
3、将P1、P2重复上述步骤,直到各部分中只剩1个数据
4、数据完成升序排列
示例:
原始数据:
{3,9,8,5,2,1,6}
第1步:选取第1个数据:3
第2步:将数据分成2部分,左边≤3,右边大于>3:
{2,1} {3} {9,8,5,6}
第3步:将各部分重复以上步骤,直到每部分只剩1个数据:
{2,1} => {1} {2}
{9,8,5,6} => {8,5,6} {9}=> {5,6} {8} {9}=> {5} {6} {8} {9}
第4步:数据完成升序排列:
{1} {2} {3} {5} {6} {8} {9}
程序中数据通常保存在数组中,以int类型的数组为例,可以将上面的步骤写成一个quickSort函数原型:
quickSort(int begin, int end) {
//begin为数组的第一个数据的索引值,end为数组的最后一个数据的索引值+1
//如果只有1个数据或0个数据,则程序返回
if( begin == end || begin == (end-1) ) return;
int p = in[begin];//p为选择的参考数据,选择第一个数据
int a = begin +1; //a作为2部分数据分界线的索引值
int b = a;//b为待比较的数据的索引值
for( ; b < end; b++) {//将数组中的各个数据依次与参考数据进行比较
if( in[b] < p) { //如果该数据<参考数据则将其移动到左边
if(a == b){a++; continue;} //如果该数据已经在左边则不动
int temp = in[a];//将数据移动到左边
in[a] = in[b];
in[b] = temp;
a++;//将分界线右移
}
}
in[begin] = in[a-1];//讲参考值移动到2组数据中间
in[a-1] = p;
if( a-1 > begin){ // 如果左边有数据则将其重复上述步骤
quickSort(begin, a);
}
if( end-1 > a ) {// 如果右边有数据则将其重复上述步骤
quickSort(a, end);
}
return; // 如果无数据返回
}
下面设计一个QuickSort类,包含了静态函数sort(),可以对任意类型数组进行排序。如果为对象类型数组,则该对象类型必须实现Comparable接口,这样才能使用compareTo函数进行比较。
使用了最基本的快排算法,没有进行优化处理。
源代码如下:
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;
public class QuickSort {
@SuppressWarnings("unchecked")
//对上述快排函数原型修改,使其可以对任意对象类型数组进行排序。这个函数为内部使用,外部排序函数接口为sort(),sort函数要求对象必须实现Comparable接口,可以提供编译时类型检测,见后文。
private static void quickSort(Object[] in,int begin, int end) {
if( begin == end || begin == (end-1) ) return;
Object p = in[begin];
int a = begin +1;
int b = a;
for( ; b < end; b++) {
//该对象类型数组必须实现Comparable接口,这样才能使用compareTo函数进行比较
if( ((Comparable
运行main函数测试,从输出可以看出QuickSort类工作正常:
int[] before sorting: 65 48 92 26 3 8 59 21 16 45
int[] after sorting: 3 8 16 21 26 45 48 59 65 92
String[] before sorting: b a e d f c
String[] after sorting: a b c d e f
LinkedList before sorting: b a e d f c
LinkedList after sorting: a b c d e f