快速排序,顾名思义是一种效率较高的排序算法,采用一种分治的思想完成排序。
原理
取一个数作为基数,然后通过把比基数小的数移动到基数左边,把基数大的数移动到基数右边,然后再按照这个逻辑依次处理左右两边的数据,直到所有完成整个排序过程。
分析
1、一般使用第一个或者最后一个数作为初始基数。
2、设置一头一尾的两个方向坐标,从尾开始的遇到比基数小的就交换,从头开始的遇到比基数大的就交换。
3、最后中间数为基数,左边均为比基数小的数,右边均为比基数大的数。
4、递归重复上述过程即可。
时间复杂度
最差情况下为:O(n^2)
最好情况下为:O(nlogn)
平均时间复杂度为:O(nlogn)
示例
假设有初始数据如下
头下标 i = 0,尾下标 j = 7,基数取数组下标第一个元素 5
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
5 | 2 | 8 | 4 | 9 | 7 | 1 | 3 |
从尾向头遍历,3 < 5 ,用3填到头下标0的位置,头下标向后移动一位 i = 1,j = 7
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
3 | 2 | 8 | 4 | 9 | 7 | 1 | 3 |
从头向尾遍历,2 < 5 不动,头下标向前移动一位 i = 2,j = 7
继续从头向尾遍历,8 > 5,用8填到尾下标7的位置,尾下标向前移动一位 i = 2,j = 6
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
3 | 2 | 8 | 4 | 9 | 7 | 1 | 8 |
从尾向头遍历,1 < 5 ,用1填到头下标2的位置,头下标向后移动一位 i = 3,j = 6
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
3 | 2 | 1 | 4 | 9 | 7 | 1 | 8 |
从头向尾遍历,4 < 5 不动,头下标向前移动一位 i = 4,j = 6
继续从头向尾遍历,9 > 5,用9填到尾下标6的位置,尾下标向前移动一位 i = 4,j = 5
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
3 | 2 | 1 | 4 | 9 | 7 | 9 | 8 |
从尾向头遍历,7 > 5 不动,尾下标向前移动一位 i = 4,j = 4
头尾下标相等,把基数5赋值给下标4,此轮处理结束。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
3 | 2 | 1 | 4 | 5 | 7 | 9 | 8 |
此时5左边的数都小于5,右边的数都大于5,之后再依次对左右两边的数据做重复的操作即可。
Java版代码实现
public class QuickSort {
static int[] arr = {5, 2, 8, 4, 9, 7, 1, 3};
public static void main(String[] args) {
quick(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
private static void quick(int[] arr, int left, int right) {
if (left < right) {
int i = left;
int j = right;
int k = arr[left];
while (i < j) {
while (i < j && k < arr[j]) {
j--;
}
if (i < j) {
arr[i] = arr[j];
i++;
}
while (i < j && k > arr[i]) {
i++;
}
if (i < j) {
arr[j] = arr[i];
j--;
}
}
arr[i] = k;
quick(arr, left, i - 1);
quick(arr, i + 1, right);
}
}
}