点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

今天将为大家介绍常用的十大排序算法中最简单的五种(冒泡、选择、插入、希尔、归并),主要从:过程图解、算法思想、代码实现、算法分析这四个方面讲解,建议大家看完之后自己动手练习加强记忆!

注:本文使用的复杂度均为最坏复杂度

一、冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,一层一层的将较大的元素往后移动,其现象和气泡在上升过程中慢慢变大类似,故成为冒泡排序

1.过程图解

2.算法思想

  1. 从第一个和第二个开始比较,如果第一个比第二个大,则交换位置,然后比较第二个和第三个,逐渐往后

  2. 经过第一轮后最大的元素已经排在最后,所以重复上述操作的话第二大的则会排在倒数第二的位置。

  3. 那重复上述操作n-1次即可完成排序,因为最后一次只有一个元素所以不需要比较

3.代码实现

def bubble_sort(arr):
"""冒泡排序"""
# 第一层for表示循环的遍数
for i in range(len(arr) - 1):
# 第二层for表示具体比较哪两个元素
for j in range(len(arr) - 1 - i):
if arr[j] > arr[j + 1]:
# 如果前面的大于后面的,则交换这两个元素的位置arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr

4.算法分析

冒泡排序是一种简单直接暴力的排序算法,为什么说它暴力?因为每一轮比较可能多个元素移动位置,而元素位置的互换是需要消耗资源的,所以这是一种偏慢的排序算法,仅适用于对于含有较少元素的数列进行排序。

  1. 稳定性:我们从代码中可以看出只有前一个元素大于后一个元素才可能交换位置,所以相同元素的相对顺序不可能改变,所以它是稳定排序

  2. 比较性:因为排序时元素之间需要比较,所以是比较排序

  3. 时间复杂度:因为它需要双层循环n*(n-1)),所以平均时间复杂度为O(n^2)

  4. 空间复杂度:只需要常数个辅助单元,所以空间复杂度为O(1),我们把空间复杂度为O(1)的排序成为原地排序(in-place)

  5. 记忆方法:想象成气泡,一层一层的往上变大

二、选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,所以称为:选择排序

1.过程图解

2.算法思想

  1. 设第一个元素为比较元素,依次和后面的元素比较,比较完所有元素找到最小的元素,将它和第一个元素互换

  2. 重复上述操作,我们找出第二小的元素和第二个位置的元素互换,以此类推找出剩余最小元素将它换到前面,即完成排序

3.代码实现

def selection_sort(arr):
"""选择排序"""
# 第一层for表示循环选择的遍数
for i in range(len(arr) - 1):
# 将起始元素设为最小元素min_index = i
# 第二层for表示最小元素和后面的元素逐个比较
for j in range(i + 1, len(arr)):
if arr[j] < arr[min_index]:
# 如果当前元素比最小元素小,则把当前元素角标记为最小元素角标min_index = j
# 查找一遍后将最小元素与起始元素互换arr[min_index], arr[i] = arr[i], arr[min_index]
return arr

4.算法分析

选择排序冒泡排序很类似,但是选择排序每轮比较只会有一次交换,而冒泡排序会有多次交换,交换次数比冒泡排序少,就减少cpu的消耗,所以在数据量小的时候可以用选择排序,实际适用的场合非常少

  1. 比较性:因为排序时元素之间需要比较,所以是比较排序

  2. 稳定性:因为存在任意位置的两个元素交换,比如[5,  8, 5, 2],第一个5会和2交换位置,所以改变了两个5原来的相对顺序,所以为不稳定排序

  3. 时间复杂度:我们看到选择排序同样是双层循环n*(n-1)),所以时间复杂度也为:O(n^2)

  4. 空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)

  5. 记忆方法:选择对象要先选最小的,因为嫩,哈哈

三、插入排序

插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

1.过程图解

2.算法思想

  1. 从第二个元素开始和前面的元素进行比较,如果前面的元素比当前元素大,则将前面元素 后移,当前元素依次往前,直到找到比它小或等于它的元素插入在其后面

  2. 然后选择第三个元素,重复上述操作,进行插入

  3. 依次选择到最后一个元素,插入后即完成所有排序

3.代码实现

def insertion_sort(arr):
"""插入排序"""
# 第一层for表示循环插入的遍数
for i in range(1, len(arr)):
# 设置当前需要插入的元素current = arr[i]
# 与当前元素比较的比较元素pre_index = i - 1
while pre_index >= 0 and arr[pre_index] > current:
# 当比较元素大于当前元素则把比较元素后移arr[pre_index + 1] = arr[pre_index]
# 往前选择下一个比较元素pre_index -= 1
# 当比较元素小于当前元素,则将当前元素插入在 其后面arr[pre_index + 1] = current
return arr

4.算法分析

插入排序的适用场景:一个新元素需要插入到一组已经是有序的数组中,或者是一组基本有序的数组排序

  1. 比较性:排序时元素之间需要比较,所以为比较排序

  2. 稳定性:从代码我们可以看出只有比较元素大于当前元素,比较元素才会往后移动,所以相同元素是不会改变相对顺序

  3. 时间复杂度:插入排序同样需要两次循坏一个一个比较,故时间复杂度也为O(n^2)

  4. 空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)

  5. 记忆方法:想象成在书架中插书:先找到相应位置,将后面的书往后推,再将书插入

四、希尔排序

希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本,它与插入排序的不同之处在于,它会优先比较距离较远的元素,该方法因D.L.Shell于1959年提出而得名。

1.过程图解

2.算法思想

希尔排序的整体思想是将固定间隔的几个元素之间排序,然后再缩小这个间隔。这样到最后数列就成为了基本有序数列,而前面我们讲过插入排序对基本有序数列排序效果较好。

  1. 计算一个增量(间隔)值

  2. 对元素进行增量元素进行比较,比如增量值为7,那么就对0,7,14,21…个元素进行插入排序

  3. 然后对1,8,15…进行排序,依次递增进行排序

  4. 所有元素排序完后,缩小增量比如为3,然后又重复上述第2,3步

  5. 最后缩小增量至1时,数列已经基本有序,最后一遍普通插入即可

已知的最增量式是由 Sedgewick 提出的 (1, 5, 19, 41, 109,…),该步长的项来自 9 4^i - 9 2^i + 1 和 4^i - 3 2^i + 1 这两个算式。这项研究也表明 “比较在希尔排序中是最主要的操作,而不是交换。用这样增量式的希尔排序插入排序堆排序都要快,甚至在小数组中比快速排序还快,但是在涉及大量数据时希尔排序还是比*快速排序慢。

3.代码实现

def shell_sort(arr):
"""希尔排序"""
# 取整计算增量(间隔)值gap = len(arr) // 2
while gap > 0:
# 从增量值开始遍历比较
for i in range(gap, len(arr)):j = icurrent = arr[i]
# 元素与他同列的前面的每个元素比较,如果比前面的小则互换
while j - gap >= 0 and current < arr[j - gap]:arr[j] = arr[j - gap]j -= gaparr[j] = current
# 缩小增量(间隔)值gap //= 2
return arr

4.算法分析

  1. 比较性:排序时元素之间需要比较,所以为比较排序

  2. 稳定性:因为希尔排序是间隔的插入,所以存在相同元素相对顺序被打乱,所以是不稳定排序

  3. 时间复杂度:   最坏时间复杂度O(n^2)平均复杂度为O(n^1.3)

  4. 空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)

  5. 记忆方法:插入排序是每轮都是一小步,希尔排序是先大步后小步,它第一个突破O(n2)的排序算法。联想起阿姆斯特朗登月之后说:这是我个人一小步,却是人类迈出的一大步。

五、归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序适用于子序列有序的数据排序。

1.过程图解

2.算法思想

归并排序是分治法的典型应用。分治法(Divide-and-Conquer):将原问题划分成 n 个规模较小而结构与原问题相似的子问题;递归地解决这些问题,然后再合并其结果,就得到原问题的解。从上图看分解后的数列很像一个二叉树。

  1. 使用递归将源数列使用二分法分成多个子列

  2. 申请空间将两个子列排序合并然后返回

  3. 将所有子列一步一步合并最后完成排序

3.代码实现

def merge_sort(arr):
"""归并排序"""
if len(arr) == 1:
return arr
# 使用二分法将数列分两个mid = len(arr) // 2left = arr[:mid]right = arr[mid:]
# 使用递归运算
return marge(merge_sort(left), merge_sort(right))def marge(left, right):
"""排序合并两个数列"""result = []
# 两个数列都有值
while len(left) > 0 and len(right) > 0:
# 左右两个数列第一个最小放前面
if left[0] <= right[0]:result.append(left.pop(0))
else:result.append(right.pop(0))
# 只有一个数列中还有值,直接添加result += leftresult += right
return result

4.算法分析

  1. 比较性:排序时元素之间需要比较,所以为比较排序

  2. 稳定性:我们从代码中可以看到当左边的元素小于等于右边的元素就把左边的排前面,而原本左边的就是在前面,所以相同元素的相对顺序不变,故为稳定排序

  3. 时间复杂度:   复杂度为O(nlog^n)

  4. 空间复杂度:在合并子列时需要申请临时空间,而且空间大小随数列的大小而变化,所以空间复杂度为O(n)

  5. 记忆方法:所谓归并肯定是要先分解,再合并

总结

今天给大家介绍的五种排序是比较简单的排序,建议大家自己动手敲几遍代码,书读百遍,其义自现。要求大家必须理解&记住它们的算法原理,因为代码是永远记不住的,只要记住原理你就能用伪代码实现。为了方便大家记忆我在每个算法分析最后给出了自己的记忆方法,如果你有更合适的记忆方法,欢迎在下方留言,同时也欢迎大家转发分享

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

排序算法—Python实现十大常用排序算法相关推荐

  1. 排序算法——(2)Python实现十大常用排序算法

    上期为大家讲解了排序算法常见的几个概念: 相关性:排序时是否需要比较元素 稳定性:相同元素排序后是否可能打乱 时间空间复杂度:随着元素增加时间和空间随之变化的函数 如果有遗忘的同学可以看排序算法--( ...

  2. Python实现十大经典排序 I

    Python实现十大经典排序 I 摘要: 本博客主要介绍冒泡排序.选择排序.插入排序.快速排序.归并排序等五种排序方法思想及Python实现. 文档版本 版本号 更新时间 作者 更新章节 更新概述 V ...

  3. 【Python】用Python实现十大经典排序算法

    来源:Python数据之道 (ID:PyDataLab) 作者:阳哥 大家好,我是阳哥. 最近一段时间,我在微信视频号「Python数据之道」上陆陆续续发布了10种经典排序算法的动画实现. 今天,想以 ...

  4. Python 实现十大经典排序算法

    目录 排序算法分类 一.冒泡排序(Bubble Sort) 1.原理 2.步骤 3.动画演示 4.代码实现 5.具体示例 二.选择排序(Selection Sort) 1.原理 2.步骤 3.动画演示 ...

  5. 用 Python 实现十大经典排序算法

    作者 | 我是阳哥 来源 | Python数据之道 今天,详细的跟大家分享下 10 种经典排序算法. 10种经典排序算法包括冒泡排序.选择排序.快速排序.归并排序.堆排序.插入排序.希尔排序.计数排序 ...

  6. 用Python实现十大经典排序算法

    来源:Python数据之道 (ID:PyDataLab) 作者:阳哥 大家好,我是阳哥. 最近一段时间,我在微信视频号「Python数据之道」上陆陆续续发布了10种经典排序算法的动画实现. 今天,想以 ...

  7. 利用Python实现十大经典排序算法(附代码流程)

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 作者:hustcc 来源:https://github.com/hustcc/JS ...

  8. 【数据结构与算法】之深入解析十大常用排序算法的原理分析和算法实现

    一.十大排序算法的对比 排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 排序方式 稳定性 冒泡排序 O(n2) O(n) O(n2) O(1) In-place 稳定 选择排序 O(n2) ...

  9. 【算法基础】十大经典排序算法(动图)

    算法分类 冒泡排序(重点) 选择排序 插入排序 归并排序(重点) 快速排序(重点) 堆排序(重点) 计数排序 基数排序 本文的重点排序方法在:冒泡排序,归并排序,快速排序,桶排序. 文末有学习资料免费 ...

最新文章

  1. 支付接入开发的陷阱有多深?
  2. dicom文件_DICOM数据转成NIfTI数据
  3. 作为一名程序员,谁没跳过槽,“6”招让你“空降”大厂
  4. 2018-03-26
  5. 一本通1596动物园
  6. WEB页面性能指标与建议
  7. aws rds监控慢sql_如何将AWS RDS SQL Server与AWS Glue连接
  8. 用vsftp建立个人ftp站点
  9. 奇妙的 10^n + 1
  10. php测试宽带速度慢,性能测试问题排查一例——网络带宽瓶颈
  11. java之mybatis之缓存
  12. ★★★【加快】页面的【加载速度】,先减少图片请求★
  13. vue把数据导出为Excel表格的方法
  14. p30升级鸿蒙能支持5G网络吗,华为p30支持5g吗
  15. 简单分享,阿里巴巴测试岗4轮面经(已拿34K+ offer)
  16. 我的梦想就是不工作,有什么错?
  17. 今天在淘宝网购物,保证你省钱!又见系统升级Bug?(看图片)
  18. excel中引用power bi模型数据
  19. R语言-将数据按照月份、季度、年份划分及求某个代码(地名、产业名等)对应的累积值
  20. 拓扑关系——九交模型

热门文章

  1. 锐捷交换机配置snmp版本_锐捷交换机开启snmp配置命令
  2. localStorage.setItem()使用
  3. Design Support Library汇总
  4. 大数据项目-1.安装虚拟机vm16+ubuntu(二:报错Please remove the installation medium,then press enter)
  5. Chrome游览器Google商店下载crx文件
  6. PDF编辑器的文字和图片怎么改
  7. Mesh BRep Shapes
  8. 【机器学习】AGNES层次聚类算法
  9. 单片机5V转3.3V电平你能想到几种方式,这里有19种,你都会吗?
  10. Python 二进制位运算