快速排序是一种高效的排序算法,也是面试常考的一种算法,大多数人畏惧和逃避算法,不是由于算法有多难,而是没有找到合适的老师,简单说就是没有通俗易懂的文章,致使学习者越看越懵,看完即忘的现象。今天我想尝试作一个“好老师”,用通俗易懂的方式讲解一下什么是快速排序。java
不少文章,上来就用某种语言,开始啪啦啪啦写代码,不熟悉该种语言的学者,一脸蒙蔽,又是一篇水文。或者跟着代码看了一下,感受会了,关掉网页,脑子:what???我刚才看了啥?面试
算法与编程语言无关,它是一种思想,理解了思想,编程语言只是一种实现方式。算法
OK,来看看快速排序的思想编程
假设如今有一个乱序的数组:数组
5 3 6 1 4 8 2 7
复制代码
快速排序核心思想:编程语言
随意找一个目标值,放在数组的某个下标,使得该下标的左侧数值都小于目标值,右侧数值都大于目标值学习
随意选一个目标值,假如就数组的第一个数值 5,如今须要将 5 移动到数组的某个下标 K 上,而且以 K 为临界点,左边的数小于 5 ,右边的数大于 5 ,该怎么操做?ui
使用一种二分交换的思想,以什么分?如下标 K 分。须要解决2个问题,如何交换数值,如何肯定下标 Kspa
模拟两我的,从数组 5 3 6 1 4 8 2 7
两边开始探测,先从右往左开始找一个小于5的数,再从左往右找一个大于5的数,而后交换数据,交换完成继续探测,直到两我的相遇code
模拟的两我的暂且称它们为:"探子j" , "探子i"
开始时,"探子j" 站在 右边,"探子i" 站在 左边
5 3 6 1 4 8 2 7 => 5 3 2 1 4 8 6 7
在现有的位置上继续探测,仍是从 "探子j" 开始(强调,每次都是从探子j开始),继续向左移动(j- -),找到 4 知足,停下来;而后 "探子i" 开始继续往右寻找,走到 4 没有找到大于 5 的数字两我的就相遇了。(若是相遇以前能找到知足的数值,则依旧交换这两个值)
当两个探子相遇的下标位置,就是下标 K,此时将下标 K 数值与以前选择的 基准数 相互交换,实现 K 的左边都小于基准数,右边大于基准数
4 3 2 1 5 8 6 7
以 K (5) 作分界点,将数组分为两个部分,而后将左右两边的子数组在执行上述操做,最终将整个数组完成排序
OK,以上就是快速排序的基本思想,应该能够理解吧。
理解了思想,就按照这算法的思想一步步写代码就好了,本人熟悉java,就用java做为编程语言撸一遍
/** * 快速排序 * * @param array 目标数组 * @param left 数组最左下标值 * @param right 数组最右下标值 */
public static void quickSort(int[] array, int left, int right) {
//防止数组越界(这一步最后再回来理解)
if (left >= right) return;
int base = array[left];//基准数
int i = left, j = right;//左探子i,右探子j
int temp;//用于交换的临时变量
while (i != j) {//两个探子相遇前
//找出小于 基准数 的下标,当大于等于 基准数 的时候,探子j 向左移动便可(j--)
while (array[j] >= base && i < j) {
j--;
}
//找出大于 基准数 的下标,当小于等于 基准数 的时候,探子i 向右移动便可(i++)
while (array[i] <= base && i < j) {
i++;
}
//通过上面两个循环以后,探子j,探子i 都会停在符合条件的值的下标上面,而后就能够进行交换值啦
if (i < j) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
//通过上面的循环以后会触发 i=j 的条件(即两个探子相遇),此时将基准值的数与i或者j(随便哪一个都同样)下标的值交换,完成一次交换探测
array[left] = array[i];//基准值的位置
array[i] = base;//基准值
//完成交换以后再对左右两边的子数组进行递归调用走上面的方法,完成整个数组的排序
quickSort(array, left, i - 1);//左边
quickSort(array, i + 1, right); //右边
}
复制代码
读注释!读注释!读注释!而后就是,使用快排算法排序数组
int[] array = new int[]{5, 3, 6, 1, 4, 8, 2, 7};
quickSort(array, 0, array.length - 1);//快速排序
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");//打印排序后的数组
}
复制代码
结果输出
1 2 3 4 5 6 7 8
复制代码