您的位置:首页 > 其它

算法学习笔记-排序

2016-02-20 23:00 169 查看
为了长远的目标,今年开始重新学习计算机基础知识。从豆瓣读书上把tag为编程的,9分以上的书差不多都买了。

写写博客,仅为了自己复习巩固。

看的书是《算法(第四版)》号称是最简单的入门书。

全书都是用的java写的实例,不错,看着亲切,但是代码风格我是不喜欢,作者喜欢省略花括号,条件的执行语句如果一条,会将条件语句,执行语句放一行。

不过这个不是重点,代码风格上我是坚持的《重构》里的格式。

学习么,循序渐进,我也不指望看第一遍就全看懂,所以书内的大部分习题,准备在第二轮巩固学习时再看。

从这个排序这一章节,学到了初级排序与高级排序;

初级排序:

选择排序:每一轮找到最小的和每轮开始位置的值替换。时间复杂度O(N^2)

插入排序:每一轮开始位置的值与前面有序的部分比较,确定该插入的位置,然后将大于该值的往右移动一位,将该值插入。时间复杂度O(N^2)

希尔排序:基于插入排序,插入排序的最坏情况是最小值在最右侧,将这个值移动到指定位置,操作会比较多。希尔排序定义了一个增量,

我这书里是定义 while(h<N/3){h=h*3+1}  h为:1,4,13.。。。,根据数据大小,会执行多轮的插入排序。

假设数组大小为15个,那h初始值4,也就是有2轮。第一轮的时候,0,4,8,12->1,5,9,13->2,6,10,14.....按这样的子数组执行插入排序,

这样,右侧的小值就可以高效的移动到左侧,每一次的插入排序都使整个数组更有序。基于这个增量,时间复杂度:O(N^6/5)

高级排序:

归并排序:将一个大数组一分为二,不断的分,子数组有序后,将2个有序子数组不断归并,最后就整体有序了。在操作过程中需要额外的N空间做归并用,

时间复杂度O(NlogN)

快速排序:取一个值,一般取low位,然后切分操作,使切分后,小于等于该值的在该值左侧,大于等于的在该值右侧,不断这样的操作,最终子数组都有序了整体就有序了。

为了避免最坏情况,就是low位总是最小值或最大值,造成切分后一边几乎没有,都在另一边,所以排序前,先乱序下。

一般常用的是三向切分快速排序,在切分后,会有三段数据,小于切分值的,等于切分值,大于切分值的,中间这段就已经是最终位置了,左右两边再继续快排。

时间复杂度为O(N~NlogN)

注:排序还有个稳定性的概念,插入排序与归并排序是稳定的。

例如我有个对象是航班,对象里有3个值,其中有【出发地】与【出发时间】,假设我的初始数据是【出发时间】升序的,如果使用了稳定的排序算法去排序【出发地】,那排序后的数据是【出发地】升序【出发时间】升序,否则就是【出发地】升序【出发时间】无序

在Java内置的sort方法,对于基本类型使用的是快速排序,对于引用类型使用的归并排序。

堆排序:先将数据放入一颗二叉树(数组实现),将它堆有序(每个节点都大于等于它的2个子节点),然后不断的将最大值放到数组末尾,然后再使剩下的树堆有序,最后树没了,数组有序了。

这个有点抽象,得看着图才好理解。书里是将一个数组模拟成二叉树,下标0不用,1为根节点,2,3为1的子节点,依次下去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序