排序算法总结

基本概念

1. 时间复杂度

  • 定义:一个算法流程中,常数操作数量的指标,这个指标叫做O,big O。具体为,如果常数操作数量的表达式中,只要高阶项,不要低阶项,也不要高阶项系数之后,剩下的部分记为f(N),那么该算法的时间复杂度为O(f(N))
  • 常数操作与数据量没有关系,时间复杂度和数据量有关,只要高阶项,且不要系数。

2. 空间复杂度

  • 定义:给的数组不占额外空间,额外空间是为了完成排序还需要多少辅助的空间。
  • 有限的几个变量是O(1),长度为N的数组为O(N)。

3. 稳定性

  • 定义:一个数组在排完序后,相等的值的相对次序不发生变化。
  • 稳定性的作用:对引用类型的数据进行排序

4. 测试用例

随机生成数组,用自带的sort函数进行结果验证。引用类型数据还要写比对函数。

5. 递归和迭代

  • 所有递归都可以改为迭代。递归是系统自己压栈,迭代就是自己压栈。
  • 递归是自己调用自己,迭代是用while循环。
  • 生产环境里不要用递归。

基于比较的的排序

时间复杂度不可能低于O(N*logN)

一、冒泡排序

  • 时间复杂度:O(N^2)
  • 额外空间复杂度:O(1)
  • 是否可实现稳定性:是

1. 原理

从第一个数开始,比较相邻的两个数,大的数往下沉,每次排好未排序序列中的最大数。

2. 交换两个数据的方法

(1)用temp变量保存。

var temp=a;
a=b;
b=temp;

(2)异或运算(XOR)。
异或满足交换律和结合律,就是无进位相加,1+0=1,0+1=1,1+1=0。
缺点:float类型且引用地址相同不能用该方法。

a=a^b;
b=a^b;
a=a^b;

3. 时间复杂度

N+N-1+....+1=N(N+1)/2;只要高阶项,不要低阶项,也不要高阶项系数,因此为O(N²)。

4. 空间复杂度

冒泡排序只需要几个有限的变量空间,所以是O(1)。

5. 稳定性

相等的不交换,大于时交换,就可以保证稳定性。

二、插入排序

  • 时间复杂度O(N^2)
  • 额外空间复杂度O(1)
  • 是否可实现稳定性:是

1. 原理(类似扑克牌)

插入排序就是,在有序区中,从后往前,遇到大于自身的数就进行交互换,看什么时候停下来。直到最后一个数加入有序区。

2.空间复杂度

最差情况下1+...+N-1=(N-1)N/2,因此为O(N²)。

3. 空间复杂度

只需要几个有限的变量空间,所以是O(1)。

4. 稳定性

相等的不交换,只有大于时交换,就可以保证稳定性。

三、选择排序

  • 时间复杂度O(N^2)
  • 额外空间复杂度O(1)
  • 是否可实现稳定性:否

1. 原理

每次从无序区中选择最小的数加入到有序区的末尾。与相应位置的数据进行交换

2.空间复杂度

每次遍历找最小值:N+N-1+....+1=N(N+1)/2,因此为O(N²)。

3. 空间复杂度

只需要几个有限的变量空间,所以是O(1)。

四、快速排序

  • 时间复杂度O(N*logN)
  • 额外空间复杂度必须为O(logN)
  • 是否可实现稳定性:额外空间复杂度为O(logN)的情况下不可以,增加额外空间可以,但快排要求的就是空间复杂度为O(logN)。

logN默认以2为底,代表长度为N的数组可以二分多少次。

1、求M([3,1,5,4,2])中不在N([9,2,7])中的数的集合,即求M-N的差集

(1)暴力搜索

将M中每个数依次与N中的数进行遍历对比,不在N中就打印,在N中就直接跳过。
时间复杂度O(MN)。

(2)先排序再二分
  • N先排序,M中每个数通过二分搜索的方式确定有没有。
  • 排序时间复杂度为O(A),二分搜索时间复杂度为O(MlogN)。该方法的总时间复杂度为O(A)+O(MlogN),化简后为其中的大者。
  • L+(R-L)/2 = L+(R-L)>>1,位运算比除法快

2、随机快排原理

  • 经典快排:将小于等于划分为一个区域。
  • 改进快排:将小于和等于分为两个区域。随机找一个数作为基准,小于这个数的放左边,等于的放中间,大于的放右边,然后再递归将左右边进行排序
3、代码实现

(1)如果为null或者length<2,直接返回
(2)随机选择一个数作为基准数,交换至数组末尾
(3)partition返回等于基准数的左右边界下标,再递归的对小于区和大于区进行快排。

4、时间复杂度

(1)选一个随机的划分数,为O(1)。
(2)partition过程,将数组划分为三个区间,就是遍历一次数组的过程为O(N)。
(3)左侧和右侧分别进行了递归。

  • 最差情况下,每次O(N)只能搞定一个数(1,2,3,4,5,6选择第一个数为划分数),最终复杂度为O(N²)。因此通过随机选择划分值可以在概率上尽量避免出现最差的情况。
  • 最好情况下,左右差不多都是N/2,2T(N/2),用master公式计算,a=b=2,d=1,因此T(N)=N*logN。master公式只能用于递归规模一样的情况。
  • 概率累加得到的期望值也为N*logN。

5、空间复杂度

因为左右需要递归排序,过程中需要不断记录划分值的位置,因此空间复杂度为断点树的高度,即log(2)(N)

五、归并排序

  • 时间复杂度O(N*logN)
  • 额外空间复杂度O(N)
  • 实现可以做到稳定性

1、原理

  • 递归法:将数组二分直至不能划分,即每个组都只有一个数值,然后不断合并排序。
  • 迭代法:room=1、2、4、8....不足就保持不变,不断排序合并

2、小和问题

  • 问题:将每个数的左边所有比它小的数进行累加,得到的和为小和。
  • 思路:对每个数而言,只需要知道我的右边有多少个数比我大,我就累加几次。通过归并排序,在merge的的过程中,会依次遇到所有右边比我 大的数。

3、求逆序对

  • 问题:存在多少对数对,数对中前面的数比后面的数大。
  • 思路:和小和问题同理,即对每个数而言,只需要知道我的右边有多少个数比我小,在我这个位置就产生了多少对逆序对。

六、堆排序

  • 时间复杂度O(N*logN)
  • 额外空间复杂度O(1)
  • 实现不能做到稳定性

关键步骤:heapInsert, heapify,堆的扩大和缩小操作

1、堆的概念

  • 完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。
  • 平衡二叉树(AVL树):它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树,同时,平衡二叉树必定是二叉搜索树,反之则不一定。
  • (算法上的堆,不是系统中的堆)就是一个完全二叉树,可以把一个数组在逻辑上对应成一颗完全二叉树,左孩子2i+1,右孩子2i+2,父(i-1)/2。
  • 大根堆:一定是一个完全二叉树结构,任何一个根节点都是其所在数树(子树)中的最大值。

2、原理

(1)将数组变换为大根堆。每个数和父节点的值进行比较,如果大于父节点,就交换。时间复杂度=log1+log2+log3+...+logN=O(N)。
(2)此时根节点的值最大,然后交换根节点和最后一个节点,保持最后一个节点不动,size--,超过size就代表越界。然后再构建大根堆,以此往复,每次找打最大值,直至所有数据排完序。

最重要的heapinsert(初始化构建大根堆),heapify(下沉函数),size。优先级队列的题目就是堆,建立堆的过程和任何一个堆沉下去的过程重要。

4、时间复杂度

(1)建立大根堆的过程为O(N)。
(2)heapify的过程就是树的高度,为O(logN)。
(3)N个数的时间复杂度就是O(NlogN),但常数项很大。

5、堆排和快排对比

  • 空间复杂度:堆排的空间复杂度可以做到O(1)是因为它的父子节点是通过公式的方式找到的,而快排需要记录断点的位置。
  • 时间复杂度:堆排的常数项很大,不存在最好和最坏情况;快排的常数项小。

七、希尔排序

插入排序,就是步长为1的希尔排序。

八、系统中的排序原理

  • 数据量<60,插入排序,复杂度高,常数项少;
  • 数据量大的情况下,快速排序。

不基于比较的的排序

不基于比较的排序是有瓶颈的,对数据的位数和范围有限制。

桶排序

桶排序只是一个概念,基数排序和计数排序是桶排序的具体实现。

一、计数排序

先准备好相应数量的桶,然后遍历数据,将其放入对应的桶中,最后将桶中的数依次倒出来。

二、基数排序

  1. 取位数最多的记录,其他不足该位数的补0。
  2. 按照个位数字依次放入桶中。
  3. 从0号桶开始,依次倒出来。先入桶的先倒(队列结构)。
  4. 按照十位数进桶,再倒出来,如此反复,直到最高位,结束。

三、扩展

1、求排序后的最大相邻数差值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容