【数据结构】带你初步了解排序算法

文章目录

  • [1. 排序的概念及运用](#1. 排序的概念及运用)
    • [1.1 概念](#1.1 概念)
    • [1.2 运用](#1.2 运用)
  • [2. 常见的排序算法](#2. 常见的排序算法)
    • [2.1 插入排序](#2.1 插入排序)
      • [2.1.1 直接插入排序(简单插入排序)](#2.1.1 直接插入排序(简单插入排序))
      • [2.1.2 希尔排序](#2.1.2 希尔排序)
    • [2.2 选择排序](#2.2 选择排序)
      • [2.2.1 直接选择排序(简单选择排序)](#2.2.1 直接选择排序(简单选择排序))
      • [2.2.2 堆排序](#2.2.2 堆排序)
    • [2.3 交换排序](#2.3 交换排序)
      • [2.3.1 冒泡排序](#2.3.1 冒泡排序)
      • [2.3.2 快速排序](#2.3.2 快速排序)
    • [2.4 归并排序](#2.4 归并排序)
    • [2.5 非比较排序------计数排序](#2.5 非比较排序——计数排序)
    • [2.6 非比较排序------桶排序](#2.6 非比较排序——桶排序)
    • [2.7 非比较排序------基数排序](#2.7 非比较排序——基数排序)
  • 结语

1. 排序的概念及运用

1.1 概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

1.2 运用

购物筛选排序

院校排名

2. 常见的排序算法

非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。

线性时间非比较类排序 :不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。

2.1 插入排序

2.1.1 直接插入排序(简单插入排序)

直接插入排序是一种简单的插入排序法

基本思想 :把待排序 的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

实际中我们玩扑克牌时,就用了插入排序的思想。

2.1.2 希尔排序

希尔排序法又称缩小增量法

基本思想 :先选定一个整数(通常是 g a p = n / 3 + 1 gap = n/3+1 gap=n/3+1),把待排序文件所有记录分成各组,所有的距离相等 的记录分在同一组内,并对每一组内的记录进行排序,然后 g a p = g a p / 3 + 1 gap=gap/3+1 gap=gap/3+1得到下一个整数,再将数组分成各组,进行插入排序,当 g a p = 1 gap=1 gap=1时,就相当于直接插入排序。

它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接入排序算法的。

2.2 选择排序

2.2.1 直接选择排序(简单选择排序)

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O ( n 2 ) O(n^2) O(n2)的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。

基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

2.2.2 堆排序

基本思想:堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

2.3 交换排序

所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。

交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动(以升序为例)

2.3.1 冒泡排序

冒泡排序是一种最基础的交换排序。之所以叫做冒泡排序,因为每一个元素都可以像小气泡一样,根据自身大小一点一点向数组的一侧移动。

基本思想 :它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来说并没有什么太大作用。

2.3.2 快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法

基本思想 :任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值(以升序为例),然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

2.4 归并排序

基本思想 :归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divideand Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

2.5 非比较排序------计数排序

上面介绍的都是基于比较的排序,而计数排序不需要比较就能够对整数进行排序,但注意的是这种排序算法也只能对整数进行排序。

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

特征

当输入的元素是n个0到k之间的整数时,它的运行时间是 O ( n + k ) O(n + k) O(n+k)。计数排序不是比较排序,排序的速度快于任何比较排序算法

由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。例如:计数排序是用来排序0到100之间的数字的最好的算法,但是它不适合按字母顺序排序人名。但是,计数排序可以用在基数排序中的算法来排序数据范围很大的数组。

通俗地理解,例如有 10 个年龄不同的人,统计出有 8 个人的年龄比 A 小,那 A 的年龄就排在第 9 位,用这个方法可以得到其他每个人的位置,也就排好了序。当然,年龄有重复时需要特殊处理(保证稳定性),这就是为什么最后要反向填充目标数组,以及将每个数字的统计减去1的原因。

2.6 非比较排序------桶排序

桶排序是计数排序 的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。

桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

2.7 非比较排序------基数排序

基数排序(英语:Radix sort)是一种非比较型的排序算法,最早用于解决卡片排序的问题。基数排序将待排序的元素拆分为k个关键字,逐一对各个关键字排序后完成对所有元素的排序。

如果是从第1关键字到第关键字顺序进行比较,则该基数排序称为 MSD(Most Significant Digit first)基数排序;

如果是从第k关键字到第1关键字顺序进行比较,则该基数排序称为 LSD(Least Significant Digit first)基数排序。

对于LSD来说,基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。(MSD则与之相反)

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

带你初步了解排序算法:https://blog.csdn.net/2301_80191662/article/details/142211265

十大经典排序算法总结与分析:https://blog.csdn.net/2301_80191662/article/details/142211564

相关推荐
烦躁的大鼻嘎10 分钟前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
IU宝14 分钟前
C/C++内存管理
java·c语言·c++
湫ccc14 分钟前
《Python基础》之pip换国内镜像源
开发语言·python·pip
fhvyxyci15 分钟前
【C++之STL】摸清 string 的模拟实现(下)
开发语言·c++·string
qq_4597300317 分钟前
C 语言面向对象
c语言·开发语言
菜鸟学Python26 分钟前
Python 数据分析核心库大全!
开发语言·python·数据挖掘·数据分析
C++忠实粉丝27 分钟前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
一个小坑货33 分钟前
Cargo Rust 的包管理器
开发语言·后端·rust
bluebonnet2738 分钟前
【Rust练习】22.HashMap
开发语言·后端·rust
古月居GYH38 分钟前
在C++上实现反射用法
java·开发语言·c++