快速排序的基本思想是:以某个记录的关键字为比较的基准(划分元),将整个序列划分成两组,左边记录的关键字小于等于划分元,右边记录的关键字大于等于划分元,而划分元所属记录的位置就是在最终有序序列中的位置。对左、右部分数据,再各自选取一个记录的关键字作为划分元,将两个子序列划分成更小的子序列,这样一直进行下去,最终将整个序列排序成有序序列。对划分元的选取,最简单的方法就是选取当前序列的第一个记录的关键字为划分元。
public static void main(String args[]){
int a[]={7,9,5,6,10,0,4,8};
// bubbleSort(a);
quickSort(a, 0, a.length-1);
}
//打印当前数组的内容
public static void printArray(String text,int []a){
System.out.print(text);
int n = a.length;
//遍历数组当中的内容
for(int i=0;i<n-1;i++){
System.out.print(a[i]+",");
}
System.out.println(a[n-1]);
}
/**
* 快速排序算法(需要递归调用快速划分)
* @param a 排序的数组
* @param sIndex 开始的位置
* @Param eIndex 结束的位置
*/
public static void quickSort(int a[],int sIndex,int eIndex){
System.out.println("------------------");
printArray(String.format("开始快速排序:sIndex:%d,eIndex:%d。", sIndex,eIndex),a);
int p;
if(sIndex < eIndex){
p = quickPartition(a, sIndex, eIndex);//用快速划分将数值一分为二
quickSort(a,sIndex,p-1);//将左边数组继续用快速排序
quickSort(a,p+1,eIndex);//将右边数组继续用快速排序
}
}
/**
* 快速划分
* @param a 排序的数组
* @param sIndex 开始的位置
* @param eIndex 结束的位置
* @return 划分元的位置
*/
public static int quickPartition(int a[],int sIndex,int eIndex){
if(sIndex>eIndex){//判断下标大小是否正确
System.out.println("开始下标大于结束下标");
return -1;
}
if(eIndex >= a.length){//判断数组下标是否越界
System.out.println("数组下标越界");
return -1;
}
int p;//划分元
int i,j;//分别为标记头尾的指针
i = sIndex;//头指针指向开始位置
j = eIndex;//尾指针指向结束位置
p = a[i];//划分元存储头指针位置的值
printArray("开始快速划分:", a);
System.out.println(String.format("i:%d,j:%d,p:%d",i,j,p));
while(i<j){//循环进行排序,先从尾指针开始,再头指针,直到头尾指向同一个位置(即最后的划分元的位置)
while(i<j && a[j]>p){//尾指针从尾开始查找比划分元数据小的数据,当尾指针数据比划分元大,指针左移
j--;//尾指针往左移
}
if(i<j){//此时找到当前尾指针位置
a[i] = a[j];//将当前位置的数据放入头指针
printArray(String.format("将%d位置的数据%d放入头指针位置%d:",j,a[j],i),a);
i++;//头指针开始移动
}
while(i<j && a[i]<p){//头指针从头开始查找比划分元大的数据
i++;//头指针右移
}
if(i<j){//此时找到当前头指针位置
a[j] = a[i];//将当前位置的数据放入尾指针
printArray(String.format("将%d位置的数据%d放入尾指针位置%d:",i,a[i],j),a);
j--;//尾指针开始移动
}
}
a[i] = p;//跳出循环后,此时i=j,此时为划分元的位置,将数据存入划分元
printArray(String.format("划分结束,将%d位置放入划分元%d:", i,p), a);
return i;
}
下面看运行结果: