快速排序
简介
快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影。
快速排序的基本思想是:
- 1.先从数列中取出一个数作为基准数,保存起来。
- 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 3.再对左右区间重复执行以上操作,直到各区间只有一个数。
实现
我们先拿一个数组进行举例,
第一步先把第一个元素当成基准数保存起来
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
15 | 56 | 32 | 12 | 66 | 68 | 41 | 27 | 16 | 8 |
初始化时,定义i=0, j=9, index = a[0] = 15
因为下标为0的位置的元素已经保存到了index里,所以可以理解为在下标为0的位置上挖了一个坑,然后我们再去找数据来填这个坑,快速排序其实就是找坑填坑的过程
我们从右往左找,找一个比index小的数填到坑里,当 j 等于 9 的时候满足条件,所以a[0] = a[9]; i++;这样就把0位置上的坑填了,为什么要i++呢,因为我们接下来要从左往右找比index大的数,0的位置铁定比index小,所以从下一个位置开始找,那么数组现在就是这个样子
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
8 | 56 | 32 | 12 | 66 | 68 | 41 | 27 | 16 | 8 |
现在又有一个新坑在下标为9的位置上,那么我们从左往右开始找比index大的元素,当i = 1 时满足条件,将a[9] = a[1]; j--;
数组变成
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
8 | 56 | 32 | 12 | 66 | 68 | 41 | 27 | 16 | 56 |
然后我们继续上面的操作,直到 i 和 j 相遇跳出循环,此时数组是这个样子
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
8 | 12 | 15 | 32 | 66 | 68 | 41 | 27 | 16 | 56 |
现在在我们index基准数的左边全是比index小的数,右边全是比index大的数,所以我们只要把左右分别再次进行排列就可以得到我们想要的结果
所以我们根据以上思想写出代码如下
//快速排序
public void quick_sort(int s[], int left, int right)
{
if (left < r)
{
int i = left, j = right, x = s[left];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, left, i - 1); // 递归调用
quick_sort(s, i + 1, right);
}
}
如果觉得写的方便理解,点个赞再走呗~ └(^o^)┘