大家好,我是烤鸭:
今天分享一下基础排序算法之快速排序。快速排序是内部排序(基于比较排序)中最好的比较算法。
1. 快速排序:
原理:在要排的数(比如数组A)中选择一个中心值key(比如A[0]),通过一趟排序将数组A分成两部分,其中以key为中心,key右边都比key大,key左边的都key小,然后对这两部分分别重复这个过程,直到整个有序。
整个快排的过程就简化为了一趟排序的过程,然后递归调用就行了。
思路:
1,定义i=0,j=A.lenght-1,i为第一个数的下标,j为最后一个数下标
2,从数组的最后一个数Aj从右往左找,找到第一小于key的数,记为Aj;
3,从数组的第一个数Ai 从左往右找,找到第一个大于key的数,记为Ai;
4,交换Ai 和Aj
5,重复这个过程,直到 i=j
6,调整key的位置,把A[i] 和key交换
例如 6 9 8 5 4 7(i=0,j=0)
first time: 4 9 8 5 6 7 从左向右,取>=6的(第一个为6),从右向左,取比6小的(第一个为4),交换位置(i=0,j=1)
second time: 4 5 8 9 6 7 比6大的第二个元素9,比6小的第二个元素5,交换位置(i=1,j=2)
third time: 4 5 8 9 6 7 再继续i > j了,递归原方法,45基准变成4,8967基准变成8(i=2,j=1)
forth time: 4 5 7 9 6 8 同上,8和7交换(i=2,j=5)
fifth time: 4 5 7 6 9 8 同上,9和6交换(i=3,j=4)
再同上 , 7和6交换。9和8交换。
代码实现:
public void quickSort(int[] numbers, int start, int end) {
if (start < end) {
int base = numbers[start]; // 选定的基准值(第一个数值作为基准值)
int temp; // 记录临时中间值
int i = start, j = end;
do {
while ((numbers[i] < base) && (i < end)) {
i++;
}
while ((numbers[j] > base) && (j > start)) {
j--;
}
if (i <= j) {
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
i++;
j--;
}
} while (i <= j);
if (start < j) {
quickSort(numbers, start, j);
}
if (end > i) {
quickSort(numbers, i, end);
}
}
}
耗时对比:
10W 条随机 数据 运行如图:
分别对比了冒泡排序,直插排序,希尔排序和快速排序。差距很明显。
50W 条随机 数据 运行如图:
分别对比了冒泡排序,直插排序,希尔排序和快速排序。差距很明显。
100W 条随机 数据 运行如图:
分别对比了冒泡排序,直插排序,希尔排序和快速排序。差距很明显。
总结:
快速排序(Quicksort)是对冒泡排序的一种改进。
最坏时间复杂度和插入排序相同:O(n^2)。
冒泡排序总的平均时间复杂度为:O(nlog2n) 。
各种排序方法比较:
更多排序算法:
冒泡排序 : https://blog.csdn.net/Angry_Mills/article/details/81057900
插入排序 : https://blog.csdn.net/Angry_Mills/article/details/81208700