简述

快速排序是一种排序执行效率很高的排序算法,它利用分治法来对待排序序列进行分治排序,它的思想主要是通过一趟排序将待排记录分隔成独立的两部分,其中的一部分比关键字小,后面一部分比关键字大,然后再对这前后的两部分分别采用这种方式进行排序,通过递归的运算最终达到整个序列有序,下面我们简单进行阐述。

快排思路

我们从一个数组来逐步逐步说明快速排序的方法和思路。

  1. 假设我们对数组{7, 1, 3, 5, 13, 9, 3, 6, 11}进行快速排序。
  2. 首先在这个序列中找一个数作为基准数,为了方便可以取第一个数。
  3. 遍历数组,将小于基准数的放置于基准数左边,大于基准数的放置于基准数右边
  4. 此时得到类似于这种排序的数组{3, 1, 3, 5, 6, 7, 9, 13, 11}。
  5. 在初始状态下7是第一个位置,现在需要把7挪到中间的某个位置k,也即k位置是两边数的分界点。
  6. 那如何做到把小于和大于基准数7的值分别放置于两边呢,我们采用双指针法从数组的两端分别进行比对
  7. 先从最右位置往左开始找直到找到一个小于基准数的值,记录下该值的位置(记作 i)。
  8. 再从最左位置往右找直到找到一个大于基准数的值,记录下该值的位置(记作 j)。
  9. 如果位置i<j,则交换i和j两个位置上的值,然后继续从(j-1)的位置往前(i+1)的位置往后重复上面比对基准数然后交换的步骤。
  10. 如果执行到i==j,表示本次比对已经结束,将最后i的位置的值与基准数做交换,此时基准数就找到了临界点的位置k,位置k两边的数组都比当前位置k上的基准值或都更小或都更大。
  11. 上一次的基准值7已经把数组分为了两半,基准值7算是已归位(找到排序后的位置)
  12. 通过相同的排序思想,分别对7两边的数组进行快速排序,左边对[left, k-1]子数组排序,右边则是[k+1, right]子数组排序
  13. 利用递归算法,对分治后的子数组进行排序。

快速排序之所以比较快,是因为相比冒泡排序,每次的交换都是跳跃式的,每次设置一个基准值,将小于基准值的都交换到左边,大于基准值的都交换到右边,这样不会像冒泡一样每次都只交换相邻的两个数,因此比较和交换的此数都变少了,速度自然更高。当然,也有可能出现最坏的情况,就是仍可能相邻的两个数进行交换。

快速排序基于分治思想,它的时间平均复杂度很容易计算得到为O(NlogN)。

代码实现

 /**
* 快速排序
* @param array
*/
public static void quickSort(int[] array) {
int len;
if(array == null
|| (len = array.length) == 0
|| len == 1) {
return ;
}
sort(array, 0, len - 1);
} /**
* 快排核心算法,递归实现
* @param array
* @param left
* @param right
*/
public static void sort(int[] array, int left, int right) {
if(left > right) {
return;
}
// base中存放基准数
int base = array[left];
int i = left, j = right;
while(i != j) {
// 顺序很重要,先从右边开始往左找,直到找到比base值小的数
while(array[j] >= base && i < j) {
j--;
} // 再从左往右边找,直到找到比base值大的数
while(array[i] <= base && i < j) {
i++;
} // 上面的循环结束表示找到了位置或者(i>=j)了,交换两个数在数组中的位置
if(i < j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
} // 将基准数放到中间的位置(基准数归位)
array[left] = array[i];
array[i] = base; // 递归,继续向基准的左右两边执行和上面同样的操作
// i的索引处为上面已确定好的基准值的位置,无需再处理
sort(array, left, i - 1);
sort(array, i + 1, right);
}

参考资料

1、《啊哈!算法》/ 啊哈磊著. 人民邮电出版社

最新文章

  1. MATLAB中subplot的用法
  2. Tomcat6.0+Jdk1.5+Axis1.3搭建java webservice环境,并使用c#调用该服务。
  3. 前端调试效率低?试试这10个“Chrome开发者工具”使用技巧
  4. ASP.NET MVC (一)
  5. 基于TCP协议的网络通信
  6. hdu2795 线段树
  7. ios第三方开源库
  8. Win7激活后添加grub引导Linux最简单方法
  9. dedecms导航
  10. 任意轴算法 ( Arbitrary Axis Algorithm )
  11. 命名空间引用问题 包括找不到ConfigurationManager 这个类
  12. EasyuiCombobox三级联动
  13. MSYS2 环境搭建(在Qt Creator可以设置环境变量来进行引用这些库)
  14. idea常用设置
  15. Windows7下远程操作虚拟机
  16. Bootstrap中关闭第二个模态框时出现的问题和解决办法
  17. [CQOI2013]棋盘游戏
  18. hibernate链接数据库链接池c3p0配置
  19. HTML 练习实现鼠标移到用户图像展示更多信息
  20. Example of DenseCRF with non-RGB data

热门文章

  1. jquery.one()
  2. BZOJ1453:[WC]Dface双面棋盘
  3. 一致性哈希算法原理、避免数据热点方法及Java实现
  4. phpcms后台栏目权限修改无效的原因和解决方法
  5. 《Java多线程编程核心技术》读后感(十四)
  6. uva 12452 Plants vs. Zombies HD SP (树DP)
  7. 关于Flask使用Celery的实践经验分享
  8. 在Android工程中导入外部动态连接库(so文件)
  9. Image Processing - Pseudo(False) Color Processing
  10. JQ 获取ul\ol 下面li的个数