1.基本思想
快速排序也是基于分支算法的,步骤大致如下:
(1)选择一个基准元素,通常选择第一个元素或者最后一个元素;
(2)通过一趟排序讲待排序的记录分割成独立的两个部分,其中一部分记录的元素值均比基准元素值小,另一部分记录的元素值比基准值大。
(3)此时基准元素在其排好序后的正确位置;
(4)然后分别对这两部分记录用同样的方法继续进行排序,知道整个序列有序。
在上图中只是这排序中的第一趟,第二趟依旧按此方法进行排序,在57分为左右两段进行排序。
2.实例
public class Sort {
private int[] array;
public Sort(int[] array) {
this.array = array;
}
//排序打印格式
public void display(){
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]+"\t");
}
System.out.println();
}
public void quikSort(){
recursiveQuikSort(0,array.length-1);
}
/**
* @param low 数组最小下标
* @param high 数组最大下标
*/
public void recursiveQuikSort(int low, int high){
if(low>=high){
return;
}else {
//以第一个元素为基准
int pivot = array[low];
int partition = partition(low, high, pivot);
display();
recursiveQuikSort(low, partition-1);
recursiveQuikSort(partition+1,high);
}
}
/**
* @param low 数组中最小下标
* @param high 数组中最大下标
* @param pivot 划分的基准元素
*/
private int partition(int low, int high, int pivot){
while(low < high){
while (low < high && array[high]>=pivot){
//从右端开始扫描,定位到第一个比pivot小的元素
high--;
}
swap(low,high);
while (low < high && array[low] <= pivot){
low++;
}
swap(low,high);
}
return low;
}
/**
* @param low 数组中最小下标
* @param high 数组中最大下标
*/
private void swap(int low, int high){
int temp = array[high];
array[high] = array[low];
array[low] = temp;
}
//测试方法
public static void main(String[] args) {
int[] a = {57,68,59,52,72,28,96,33,24,19};
Sort sort = new Sort(a);
System.out.print("未排序时的结果:");
sort.display();
sort.quikSort();
}
}
3.算法分析
快速排序与归并排序一样采取看分治算法,它的时间复杂度也是O(Nlog2^N).
对于分支算法一般都说如此,用递归的方法把数据项分为两组,让后调用自身来分别处理每一组数据,算法实际上是以2未底,运行时间与N*log2N成正比。
对于快速排序来说,最理想的状态是随机分布的数据,即我们任意选定的枢纽主语中间位置,有一半元素小于它,有一般元素大于它。当数据是由小到大排列或者由大到小排列是,快速排序的效率最低。假如选中的元素为数组的中值,自然是最好的选择,但是却要遍历整个数组来确定中值,这个过程可能比排列花费的时间还要长。折衷的方法的找到数组中的第一个、最后一个以及处于中间位置的元素,选出三者中的中值作为枢纽,既避免了枢纽是最值的情况,也不会像在全部元素中寻找中值那样费时间。这种方法被称为“三项数据取中”。