时间复杂度是 O(n) 的排序算法:桶排序、计数排序、基数排序,也称线性排序,他们都不是基于比较的排序算法。

一、桶排序

1、基本思想

将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行进行排序。桶内排完序之后,再把每个桶里的数据按照顺序依次取出,从而形成有序序列。

2、桶排序对要排序数据的要求非常苛刻

  • 要排序的数据需要很容易就能划分成 m 个桶,并且,桶与桶之间有着天然的大小顺序。 ==》每个桶内的数据都排序完之后,桶与桶之间的数据不需要再进行排序。
  • 数据在各个桶之间的分布是比较均匀的。==》若数据不均匀 ==》时间复杂度就将退化为 O(nlogn) 的排序算法。

3、应用

适用于 外部排序。外部排序:数据存储在外部磁盘中,数据量比较大,内存有限,无法将数据全部加载到内存中。

示例:有 10GB 的订单数据,我们希望按订单金额(假设金额都是正整数)进行排序,但是我们的内存有限,只有几百 MB,没办法一次性把 10GB 的数据都加载到内存中。这个时候该怎么办呢?

思路:

  • 先扫描一遍文件,看订单金额所处的数据范围。==》1元 ~ 10万元
  • 将所有订单根据金额划分到 100 个桶里,第一个桶我们存储金额在 1 元到 1000 元之内的订单,第二桶存储金额在 1001 元到 2000 元之内的订单,以此类推。每一个桶对应一个文件,并且按照金额范围的大小顺序编号命名(00,01,02…99)。
    • 理想情况

      • 订单金额在 1 到 10 万之间均匀分布,那订单会被均匀划分到 100 个文件中,每个小文件中存储大约 100MB 的订单数据
      • ==》可以将这 100 个小文件依次放到内存中,用快排来排序。
      • ==》 等所有文件都排好序之后,我们只需要按照文件编号,从小到大依次读取每个小文件中的订单数据,并将其写入到一个文件中,那这个文件中存储的就是按照金额从小到大排序的订单数据了。
    • 实际情况:不均匀分布 ==》针对这些划分之后还是比较大的文件,继续划分。==》直到所有文件都能读入内存位置。
      • eg:订单金额在 1 元到 1000 元之间的比较多,我们就将这个区间继续划分为 10 个小区间,1 元到 100元,101 元到 200 元,201 元到 300 元…901 元到 1000 元。

4、实现

#include <iostream>
using namespace std;void BucketSort(int *A, int Max, int Size){int B[Max+1];int i,j,count = 0;memset(B, 0, (Max+1)*sizeof(int));for (i = 0; i < Size; i++) {j = A[i];B[j] += 1;}for (i = 0; i <= Max; i++) {if (B[i] > 0) {for (j = 0; j < B[i]; j++) {A[count] = i;count++;}}}
}int main(int argc, const char * argv[])
{int A[]={1, 2, 2, 7, 4, 9, 3, 5};// 这里可以用一个O(n)的函数来实现,假如数组的手动输入的,则在输入的时候就可以获取到。// 这里直接赋值是为了排出别的因素,看着简单。int Max = 9; int Size = sizeof(A)/sizeof(int);BucketSort(A, Max, Size);for (int i = 0; i < Size; i++) {printf("%d ",A[i]);}printf("\n");return 0;
}

二、计数排序(Counting Sort)

1、基本思想

基本思路:通过对待排序序列中的每种元素的个数进行计数,然后获得每个元素在排序后的位置的信息的排序算法。

桶排序的特殊情况:桶的大小粒度不一样,每个桶内的数据值都是相同,省去了桶内排序的时间

2、适用性

只适用于在数据范围不大的场景中,而且只能给非负整数排序或在不改变相对大小的情况下可转化为非负整数。

3、实现

#include <iostream>
#include <vector>
using namespace std;void CountSort(vector<int> &arr, int maxVal) {int len = arr.size();if (len < 1)return;vector<int> count(maxVal+1, 0);vector<int> tmp(arr);for (auto x : arr)count[x]++;for (int i = 1; i <= maxVal; ++i)count[i] += count[i - 1];for (int i = len - 1; i >= 0; --i) {arr[count[tmp[i]] - 1] = tmp[i];count[tmp[i]]--;               //注意这里要减1}
}int main()
{vector<int> arr = { 1,5,3,7,6,2,8,9,4,3,3 };int maxVal = 9;CountSort(arr,maxVal);for (auto x : arr)cout << x << " ";cout << endl;return 0;
}

三、基数排序(Radix Sort)

1、基本思想

基数排序是桶排序的扩展。

基本思想:将整数按位数切割成不同的数字,然后按每个位数分别比较。

具体做法:将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

2、不同的情形

  • 数字的排序中,若存在不同长度的问题 ==》在位数短的前面补零
  • 字符串的排序,若存在不同长度的问题 ==》位数不够的可以在后面补“0”
    • 根据ASCII 值,所有字母都大于“0”,所以补“0”不会影响到原有的大小顺序。
  • 其他含义序列中,若存在不同长度的问题 ==》具体情况具体分析

七、排序(3)——线性排序相关推荐

  1. 线性排序算法分析总结

    线性排序(Linear sort),指的是 时间复杂度为 O(n) 的排序算法.之所以时间复杂度能达到线性,是因为这种排序不是基于比较的,但它的适用场景也有很大的局限性. 线性排序有三种:桶排序.计数 ...

  2. 13 | 线性排序:如何根据年龄给100万用户数据排序?

    三种时间复杂度是 O(n) 的排序算法:桶排序.计数排序.基数排序.因为这些排序算法的时间复杂度是线性的,所以我们把这类排序算法叫作线性排序(Linear sort).之所以能做到线性的时间复杂度,主 ...

  3. sql怎么实现线性排序_如何在SQL中实现排序间接

    sql怎么实现线性排序 我最近偶然发现了一个有趣的Stack Overflow问题 ,该问题本质上是用户希望确保以明确定义的顺序交付结果记录. 他们写 SELECT name FROM product ...

  4. 三种线性排序算法 计数排序、桶排序与基数排序-BYVoid

    转自:BYVoid [非基于比较的排序] 在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种,如我们最常用的快速排序和堆 ...

  5. 三种线性排序算法 计数排序、桶排序与基数排序—— 转自:BYVoid

    三种线性排序算法 计数排序.桶排序与基数排序 [非基于比较的排序] 在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种, ...

  6. 算法笔记(二)线性排序:一百万数据量如何进行快速的排序?

    线性排序:时间复杂度为 O(n)是线性的 不涉及元素之间的比较操作(但是对排序之间的数据比较苛刻) 常见的三种: 1.桶排序:将要排序的数据分到几个有序的桶里,然后由对桶内的数据再单独进行排序,排序完 ...

  7. 七种常见的排序算法总结

    目录 引言 1.什么是排序? 2.排序算法的目的是什么? 3.常见的排序算法有哪些? 一,插入排序 1.基本思想 2.代码实现 3.性能分析 4.测试 二,希尔排序(缩小增量排序) 1.基本思想 2. ...

  8. 算法导论-排序(四)计数排序(线性时间排序)

    目录 1.计数排序介绍 2.流程图 3.代码实现 4.性能分析 5.参考资料 内容 1.计数排序介绍 什么是计数排序? 计数排序是一种特殊的排序算法,之前介绍的排序算法需要对数进行两两比较,效率下界为 ...

  9. 《大话数据结构》第9章 排序 9.2 排序的基本概念与分类

    9.2 排序的基本概念与分类 9.2.1 排序的定义         排序是我们生活中经常会面对的问题.同学们做操时会按照从矮到高排列:老师查看上课出勤情况时,会按学生学号顺序点名:高考录取时,会按成 ...

最新文章

  1. matlab matlabpool,Matlab matlabpool函数undefined
  2. 索引与优化like查询
  3. noip2019集训测试赛(五)
  4. lua学习笔记-HelloWorld
  5. php中文网企业网站,闻名 PHP企业网站系统 weenCompany v5.3.0 简体中文 UTF8
  6. STM32之独立看门狗原理
  7. 如何PHP给人生日祝福,祝福偶像生日的句子 祝好朋友生日快乐说说
  8. pygame安装教程(window)
  9. win10系统的电脑如何录屏?QVE录屏大师使用教程?
  10. mysql中有关视图的概念、操作及作用
  11. 广州计算机中心杜云飞,我校学子在ISC19世界大学生超级计算机竞赛中获佳绩
  12. GSP算法与SPADE算法
  13. C#之基于winform窗体绘制简单图形
  14. `算法知识` 多边形, 凸多边形, 外接矩形
  15. opencv 将Mat转为图片数据
  16. hackthebox-Tracks-Beginner_Track-Blue
  17. 无线射频专题《无线局域网排错,第二层重传问题3@多径现象》
  18. 开发者证书、授权文件的管理
  19. 英语影视台词---三、Cinema Paradiso
  20. PyQt5之QGraphics 008 QGraphicsItem四连杆机构动画

热门文章

  1. linux 16.04系统下载,ubuntu16.04下载|ubuntu 16.04 官方完整版-520下载站
  2. java string转number_Java运算符知识点总结
  3. 只会linux和sql能维护mes系统么,MES系统软件架构介绍
  4. python 停止工作 scapy_常见问题 - Scapy 中文文档_教程_Python开发社区
  5. dmp导入数据 oracle_DM数据库的安装使用
  6. java并发实战编程pdf_「原创」Java并发编程系列25 | 交换器Exchanger
  7. opencv 图片叠加_OpenCVSharp学习之——ROI与图像叠加
  8. pandas保存新增sheet表,且不overwrite原有内容
  9. Linux 检查域名服务,linux上的域名服务
  10. mysql5.2 软件园_MySQL Server V5.5 官方安装版