排序算法总结

时间复杂度为 O ( n 2 ) O(n^2) O(n2)的排序算法:

  1. 名次排序:n(n-1)/2次比较排出名次,n次交换排好序;
  2. 选择排序:不断找出未排序元素中的最大值,将其移到数组末尾。找最大值的算法进行size-1次比较,总的比较次数为n-1+n-2+…+1=n(n-1)/2;
  3. 冒泡排序:和选择排序类似,只是找未排序元素最大值的方法是“冒泡策略”,即从数组头部开始,不断比较相邻元素的,如果左边的元素大于右边,则两者交换位置,直到把最大的元素交换到数组末尾。n次冒泡过程比较次数为n(n-1)/2
  4. 插入排序:不断往有序数组里插入新的值,从单元素数组开始。每次插入时间复杂度为 O ( n ) O(n) O(n),插入n次,总的复杂度为 O ( n 2 ) O(n^2) O(n2)

时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)的算法

1.堆排序:首先用待排序的元素初始化一个大根堆,时间复杂度为 O ( n ) O(n) O(n),每次删除大根堆的根元素,并把剩余的元素重排,时间为 O ( l o g n ) O(logn) O(logn),执行n次这样的操作,总的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
2.归并排序:(二路归并排序)利用分而治之的思想,把每个待排序的数据段,分为大致相等的两段,分别进行排序,然后再把排序后的结果归并起来,每一小段都可以继续分成两端再归并,直到分成单个元素,从而实现分而治之。算法复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)是一种稳定排序。
3.快速排序:(三值取中,或取最左端元素为支点)同样利用分而治之的思想,把待排数据分为三段,中间一段只有一个元素,左边段的元素都小于等于中间段,右边的元素都大于等于中间段,然后每一小段继续这样划分。算法复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)**。是一种不稳定排序。**普通的快排再序列本身有序的情况下,左端或有段总是空的,这是最坏情况,时间复杂度为 O ( n 2 ) O(n^2) O(n2);三值取中解决了这个问题,最坏情况下的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

时间复杂度为 O ( n ) O(n) O(n)的排序算法

1.箱子排序:将要排序的元素的所有range个取值可能,设计为range个箱子,从输入个数为n的链表的头部开始,把每个元素输出到对应值的箱子里,相同的元素在同一个箱子里,采用链表储存。最后再从箱子里把元素收集起来,即可得到一个有序的链表。把n个元素放到箱子里,时间为 Θ ( n ) \Theta(n) Θ(n),把箱子里的元素收集起来,时间最为 Θ ( r a n g e ) \Theta(range) Θ(range),总的时间复杂度为 Θ ( n + r a n g e ) \Theta(n+range) Θ(n+range)。当range和n是一个数量级的时候,时间复杂度为 Θ ( n ) \Theta(n) Θ(n)
此方法适用于箱子的range小于等于和输入元素n的情况。如果输入了10个范围在0-999内的数,即n=10,range=1000,那这个方法会很耗时。
2.基数排序:这是改进版的箱子排序。先将要排序的数根据一个基数r分解之后再对分解得到的每一部分进行箱子排序,例如,输入了10个范围在0-999的数,我们以r=10为基数,将输入的数分为个位,十位,百位,然后对于每一位分别进行箱子排序。每一位的范围都是r,时间复杂度为 Θ ( r + n ) \Theta(r+n) Θ(r+n)。当基数和输入数的数目在同一数量级时,时间复杂度变为 Θ ( r ) \Theta(r) Θ(r)
此方法适用于输入的range和远远大于n的情况。然后将range以r= Θ ( n ) \Theta(n) Θ(n)(基数和输入的数的数目在同一数量级时)为基数分解后程序的时间复杂度最低。

需要注意的是,虽然插入排序等时间复杂度为 O ( n 2 ) O(n^2) O(n2)在渐进情况下耗时很多,但在n比较小的时候性能反而比 O ( n l o g n ) O(nlogn) O(nlogn)复杂度的要好
所以STL设计的sort排序算法,把这两种综合了起来,合并成一个分段函数,当n<c(某个常数)时,采用插入排序,当n>c时采用堆排序。(不稳定排序)
stable_sort在n<c时,采用插入排序,n>c时采用归并排序(稳定排序)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值