大家好,我是烤鸭:
今天分享一下基础排序算法之快速排序。快速排序是内部排序(基于比较排序)中最好的比较算法。
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