算法相关——Java排序算法之快速排序(三)
0. 前言
本系列文章将介绍一些常用的排序算法。排序是一个非常常见的应用场景,也是开发岗位面试必问的一道面试题,有人说,如果一个企业招聘开发人员的题目中没有排序算法题,那说明这个企业不是一个“正规”的企业,哈哈,虽然有点戏谑,但是也从侧面证明了排序算法的重要性。
本文将介绍的是常见排序算法中的快速排序。
3. 快速排序
3.1 基本思想
快速排序是一种比较快的排序算法,其基本思想为设置两个指针i和j分别指向第一个和最后一个待排元素,i向后移动,j向前移动,一般选第一个数为标准数,从后面开始,j向前移动时找到第一个比标准小的数,互换位置,然后再从前面,找到第一个比标准大的数,互换位置,第一趟的结果就是标准左边的所有数都小于标准数,右边的所有数都大于标准数,分成两拨后,再对左右两拨继续递归的使用上述方法,最终使整个序列有序。
3.2 代码实现
/*
*@author Calvin
*@blog http://blog.csdn.net/seu_calvin/article/details/55193059
*@date 2017/01/31
*/ public class Order {
private int[] array;
public Order(int[] array){
this.array = array;
} public void sort() {
if(array!=null){
quickSort(array,0,array.length-1);
}
} public void quickSort(int[] array, int begin, int end){
if(begin < end){
int key = array[begin];
int i = begin;
int j = end; while(i < j){
while(i < j && array[j]>key){
j--;
}
if(i < j){
array[i] = array[j];
i++;
}
while(i < j && array[i]<key){
i++;
}
if(i < j){
array[j] = array[i];
j--;
}
}
//循环完了把最后一个空位i赋值给key
array[i] = key;
//递归完成两个自序列排序
quickSort(array,begin,i-1);
quickSort(array,i+1,end); }
} public void print() {
for(int i = 0; i < array.length; i++)
System.out.println(array[i]);
} public static void main(String[] args) {
int[] array = new int[]{3,1,5,9,6,5,0};
Order order = new Order(array);
order.sort();
order.print();
} }
输出结果略。
3.3 性能特点
快速排序是冒泡排序的一种改进,后者是相邻元素的比较交换,前者是跳跃式交换,因此总得比较次数和交换次数少了很多,因此效率较高。快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn)。快排真正消耗空间是在递归调用上,因为每次递归都要保持一些数据。而且快速排序算法是不稳定的,因为相同值的元素在排序后的相对应的位置会改变。
3.4 可以优化的点
快速排序法在性能上有着很大优势,当然快排也会有一些优化方法,但是快排本身简单易用,因此大多数情况下使用快排就足够了。下面介绍几个快排的优化方法:
(1)标准数的选择一直是第一个可能会导致算法性能很差,可以考虑选头尾中间三个数取中间大小的数为标准数,这样就能对一些情况进行优化。
(2)快排在数据量较小时性能并不比其他算法好,因此可以考虑在待排序列为10左右时,选择其他排序算法继续进行排序。
(3)利用计算机的多线程并行处理来提高快排的执行效率。这不是对算法本身的优化,而是对算法使用上的优化。
3.5 和堆排序的比较
堆排序(后面会总结到)和快排哪个效率更好呢?两者时间复杂度相同,但是空间复杂度堆排序貌似更胜一筹,答案是快速排序比堆排序的效率高很多,并且随着数据规模的扩大,二者的差距不断扩大,快速排序的优势越来越明显。因此堆排比较少被使用。原因总结如下:
(1)首先要明确第一点,数学上的时间复杂度不代表实际运行时的情况。
(2)堆排比较的几乎都不是相邻元素,对cache极不友好,堆排中比较父节点和字节点的值大小的时候,虽然计算下标会很快完成,在大规模的数据中对数组指针寻址也需要一定的时间。而快速排序只需要将数组指针移动到相邻的区域即可。
(3)堆排序中删除堆顶后的将最后的元素放到堆顶,再让其自我调整。这样有很多比较将是被浪费的,因为被拿到堆顶的那个元素几乎肯定是很小/大的,而靠近堆顶的元素又几乎肯定是很小/大的,最后一个元素能留在堆顶的可能性微乎其微,而且很有可能最终再被移动到底部。
算法相关——Java排序算法之快速排序(三)的更多相关文章
- 算法相关——Java排序算法之插入排序(四)
0. 前言 本系列文章将介绍一些常用的排序算法.排序是一个非常常见的应用场景,也是开发岗位面试必问的一道面试题,有人说,如果一个企业招聘开发人员的题目中没有排序算法题,那说明这个企业不是一个" ...
- 算法相关——Java排序算法之桶排序(一)
(代码中对应一个数组的下标),将每个元素放入对应桶中,再将所有元素按顺序输出(代码中则按顺序将数组i下标输出arrary[i]次),即为{0,1,3,5,5,6,9}. 1.2 代码实现 /* *@ ...
- 算法相关——Java排序算法之希尔排序(五)
个子块,即{3,5},{1,0},{5,2},{9,4},{6,12},将每个子块进行插入排序(即第i位与第i+5位进行比较交换),初步排序结果为{3,0,2,4,6,5,1,5,9,12}.希尔排序 ...
- 算法相关——Java排序算法之冒泡排序(二)
0. 前言 本系列文章将介绍一些常用的排序算法.排序是一个非常常见的应用场景,也是开发岗位面试必问的一道面试题,有人说,如果一个企业招聘开发人员的题目中没有排序算法题,那说明这个企业不是一个" ...
- Java排序算法之快速排序
Java排序算法之快速排序 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分 ...
- Java排序算法(三)
Java排序算法(三) 三.Java排序算法总结 从这三组时间复杂度对比中,可以看出,堆排序和归并排序是不管在什么情况下发挥稳定的,快速排序好的时候表现如天才,坏情况下比较差强人意,甚至在等待排序个数 ...
- java排序算法(五):快速排序
java排序算法(五):快速排序 快速排序是一个速度非常快的交换排序算法,它的基本思路很简单,从待排的数据序列中任取一个数据(如第一个数据)作为分界值,所有比它小的元素放到左边.所有比它大的元素放到右 ...
- java排序算法(三):堆排序
java排序算法(三)堆排序 堆积排序(HeapSort)是指利用堆积树这种结构所设计的排序算法,可以利用数组的特点快速定位指定索引的元素.堆排序是不稳定的排序方法.辅助空间为O(1).最坏时间复杂度 ...
- java排序算法之冒泡排序和快速排序
总结一下Java排序算法,以便记忆. 各类排序的时间复杂度: 排序方法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 复杂性 直接插入排序 O(n2)O(n2) O( ...
随机推荐
- 安卓开发_深入理解Content Provider
一.Content Provider概述 Content Provider用于保存和获取数据,并使其对所有应用程序可见,这是不同应用程序之间共享数据的唯一方式,因为在Android中没有提供所有应用可 ...
- 网页html随机切换背景图片
首先要准备一些图像,图像的大小(无论是尺寸大小还是数据大小)要控制好,如果太大,会使用户等不及查看全图就跳出了,如果太小,又会影响页面质量. 在script中将这些图像编为一个数组,便于调用.数组的长 ...
- OneAPM大讲堂 | Java 异常日志记录最佳实践
[编者按]本文作者是 Casey Dunham.Casey 是一位具有 10 多年经验的专业软件开发人员,以其独特的方式应对应用安全问题而闻名.本文系国内 ITOM 管理平台 OneAPM 工程师编译 ...
- 洗礼灵魂,修炼python(46)--巩固篇—如虎添翼的property
@property 在前面装饰器一章中,提过一句话,装饰器也可以用于类中,确实可以的,并且python的类也内置了一部分装饰器.并且在前两章的hasattr等四个内置方法中,也说过其用法很类似装饰器, ...
- 洗礼灵魂,修炼python(33)--面向对象编程(3)—特殊类方法__init__,公有属性,私有属性
在上一篇博文里,传入参数时,是在实例化对象后且在调用方法时才传入参数,感觉是不是有点繁琐对吧?可以在实例化的时候就传入参数吗?可以的,这就是本篇博文的要讲到的构造器——__init__(两边双下划线) ...
- 阿里云搭建JAVA WEB环境(SQL Server + TomCat + 配置域名)
假期刚刚搭完,先写个提纲,今晚写完: 1.申请一个月的免费的云服务器ECS; 2.在云服务器上安装Java开发环境+Sql Server+Tomcat; 3.购买域名并认证,绑定服务器共有IP地址; ...
- sublime text3最常用快捷键
Ctrl+Shift+P:打开命令面板 Ctrl+P:搜索项目中的文件 Ctrl+G:跳转到第几行 Ctrl+W:关闭当前打开文件 Ctrl+Shift+W:关闭所有打开文件 Ctrl+Shift+V ...
- Spring boot 直接访问templates中html文件
application.properties 在浏览器中输入http://localhost:8080/index.html 会报一个 因为Spring boot 无法直接访问templates下的文 ...
- Bash On Windows上安装JDK
1. 引言 由于实习生转正,公司给配了一台新电脑,配置不用多说,16G内存,i7-7700的CPU,128SSD的系统盘,1T的机械硬盘,虽然只有一个破核显.对于我个人而言,最重要的是系统从Windo ...
- Java计模模式之六 ----- 组合模式和过滤器模式
前言 在上一篇中我们学习了结构型模式的外观模式和装饰器模式.本篇则来学习下组合模式和过滤器模式. 组合模式 简介 组合模式是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来 ...