基本思想:
- 任取一个元素(如第一个)为中心
- 所有比它小的元素一律往前放,比它大的元素一律后放,形成左右两个子表;
- 对各个子表重新选择中心元素并依次规则调整,直到每个子表的元素只剩下一个;
每一趟的子表的形式是采用从两头向中间交替式逼近法;
由于每趟中各子表的操作都相似,可采用递归算法;
①首先拿49作为哨兵元素,自始至终都是high先从右向左移,即j--;找到比49小的元素27时停止;将这个比较小的元素移至49原来的位置,即27移动到low所指位置;
②然后low从左向右移动直至找到比哨兵元素49大的元素,即此时移动到65停止;将65移动至high此时所指位置,high继续向左移动直至遇到比49小的元素13停止,将13移动至low所指元素。
③此时low继续向右移动,遇见比49大的97,于是将97移动至high原来所指位置;接着high向左移动,哎,此时low和high指向同一个位置,这个位置就是哨兵元素49该放的位置。至此第一个哨兵元素找到了属于自己的位置。
第一趟快速排序到此结束…………给哨兵49找到了正确位置;接下来就分别针对49左侧的27-13进行类似以上的过程,对49右侧的76-49递归进行以上过程。
快速排序算法分析:
时间复杂度:O(nlogn)
- 就时间复杂度而言,快速排序是我们所讨论的所有内排序方法中最好的一个。
空间复杂度:O(logn)
- 快速排序是递归的,需要有一个栈存放每层递归调用时参数(新的low和high)。
- 最大递归调用层次数与递归树的深度一致,因此要求存储开销为O(logn)。
快速排序是不稳定的排序。
public class QuickSort {
private static int[] a = {8,2,1,9,3,5,7};
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("原数组值:");
for(int i :a) {
System.out.print(i+" ");
}
System.out.println();
System.out.println("快速排序之后的数组:");
quickSort(0,a.length-1);
for(int i= 0;i<a.length;i++) {
System.out.print(a[i]+" ");
}
}
/**
* 快速排序核心算法
* @param low
* @param high
*/
public static void quickSort(int low,int high) {
int i,j,temp;
if(low>high) {
return;
}
//利用temp存哨兵元素
temp = a[low];
i = low;
j = high;
while(i!=j) {
//从右边开始找比哨兵元素小的元素,否则继续向左走,即j--
while(a[j]>=temp && i<j) {
j--;
}
//从左边开始找比哨兵元素大的元素,否则继续向右走,即i++
while(a[i]<=temp && i<j) {
i++;
}
//当符合条件时,交换元素
if(i<j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//最后将哨兵元素 与i、j相等位置的元素交换
a[low] = a[i];
a[i] = temp;
//递归调用左边数组
if(low<i-1) {
quickSort(low,i-1);
}
//递归调用右边数组
if(high>j+1) {
quickSort(i+1,high);
}
}
}
运行结果: