性能分析
最佳情况O(n*logn)
如果算法能尽快地把原问题分为规模相对较小的问题,那么它的效率是比较好的。对快排而言,如果每次划分都能平均的将
规模缩小一半,那么这种划分就是能最快到达目的的。
如:{4,1,3,2,6,5,7} - {2,1,3},4,{6,5,7} - {1},2,{3},4,{6,5,7} - {1},2,{3},4,{5},6,{7}
最坏情况O(n^2)
反之,如果划分后规模没有太大的变化,那么效率就比较低了。
如:{7,6,5,4,3,2,1} - {1,6,5,4,3,2},7 - 1,{6,5,4,3,2},7 - 1,{2,5,4,3},6,7 - 1,2,{5,4,3},6,7 - 1,2,{3,4},5,6,7 - 1,2,3,{4},5,6,7
平均O(n*logn)
核心思想
通过左右游标寻找分界点(最左元素)的位置
递归
分治
Demo
<span style="font-size:14px;"><span style="font-size:14px;">public class MyQuickSort {
static int[] array;
public static void main(String[] args) {
input();
quickSort(0, array.length-1);
output();
}
static void input(){
System.out.println("请输入一个数组,数字之间以英文逗号分隔:");
Scanner scanner = new Scanner(System.in);
String string = scanner.next().toString(); //读取输入,直到遇到空格或换行,并转化为字符串。
String arrayString[] = string.split(","); // 分割为字符串数组
array = new int[arrayString.length]; // 定义数组长度
for(int i=0;i<array.length;i++){
array[i] = Integer.parseInt(arrayString[i]); // 整型化
}
}
static void quickSort(int left, int right){
if(left >= right) // 退出递归一定要放在函数头部
return;
int base; // 基准数
int i, j; // 左标、右标
int temp; // 中间变量
base = array[left]; // 定义左边第一个数为基准数
i = left;
j = right;
while(i<j){ // 直到左右标相遇才结束一次快排
while(array[j]>base && i<j)
j--; // 先从右向左找第一个小于等于base的数的下标,且左右标未相遇。
while(array[i]<=base && i<j)
i++; // 再从左向右找第一个大于base的数的下标,且左右标未相遇。
if(i<j){
temp = array[i]; array[i]=array[j]; array[j]=temp; // 交换两个元素
}
}
array[left]=array[i]; array[i]=base; // 左标和右标相遇的位置就是base在有序数组中的位置
quickSort(left, i-1); // 递归快排左区间
quickSort(i+1, right); // 递归快排右区间
}
static void output() {
System.out.println("经过快速排序后,结果如下:");
for(int i=0;i<array.length;i++)
System.out.print(array[i] + " ");
}
}
</span></span>