【Python】九大经典排序算法:从入门到精通的详解(冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、计数排序、基数排序、桶排序)

文章目录

    • 1. 冒泡排序(Bubble Sort)
    • 2. 选择排序(Selection Sort)
    • 3. 插入排序(Insertion Sort)
    • 4. 归并排序(Merge Sort)
    • 5. 快速排序(Quick Sort)
    • 6. 堆排序(Heap Sort)
    • 7. 计数排序(Counting Sort)
    • 8. 基数排序(Radix Sort)
    • 9. 桶排序(Bucket Sort)
    • 10. 更多实用文章
    • 11. 结语

在这里插入图片描述

排序算法对比表格

排序算法时间复杂度空间复杂度稳定性适用场景
冒泡排序O(n²)O(1)稳定小规模数据或几乎有序的数据
选择排序O(n²)O(1)不稳定数据量小且对稳定性无要求
插入排序O(n²)O(1)稳定小规模数据或几乎有序的数据
归并排序O(n log n)O(n)稳定大规模数据需要稳定性的场景
快速排序O(n log n)O(log n)不稳定大规模数据,平均情况高效
堆排序O(n log n)O(1)不稳定大规模数据,不需要稳定性
计数排序O(n + k)O(k)稳定整数且范围有限的数据
基数排序O(d*(n + k))O(n + k)稳定大规模整数或可以分位处理的数据
桶排序O(n + k)O(n)稳定均匀分布的大规模数据

1. 冒泡排序(Bubble Sort)

工作原理

冒泡排序是一种简单的交换排序算法,通过重复遍历要排序的列表,比较相邻元素并交换顺序错误的元素,直到整个列表有序。每一次遍历都会将未排序部分的最大元素“冒泡”到列表末尾。
在这里插入图片描述

实现步骤

  1. 从列表的起始位置开始,比较相邻的两个元素。
  2. 如果前一个元素比后一个元素大,则交换它们的位置。
  3. 对整个列表重复上述过程,每完成一轮遍历,未排序部分的元素数量减少一位。
  4. 当一轮遍历未发生任何交换时,意味着列表已经有序,可以提前终止算法。

Python 实现

def bubble_sort(arr):n = len(arr)for i in range(n):swapped = Falsefor j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]swapped = Trueif not swapped:breakreturn arr

优点

  • 实现简单,理解容易。
  • 对于少量数据或已经基本有序的数据,效率较高。

缺点:

  • 时间复杂度高,为 O(n²)。
  • 不适合大规模数据排序。

2. 选择排序(Selection Sort)

工作原理

选择排序是一种简单直观的排序算法。它通过多次从未排序部分选择最小(或最大)的元素,放到已排序部分的末尾,逐步完成排序过程。
在这里插入图片描述

实现步骤

  1. 从未排序部分中找到最小的元素。
  2. 将该最小元素与未排序部分的第一个元素交换位置。
  3. 缩小未排序部分的范围,重复上述过程,直到所有元素都有序。

Python 实现

def selection_sort(arr):n = len(arr)for i in range(n):min_idx = ifor j in range(i+1, n):if arr[j] < arr[min_idx]:min_idx = jarr[i], arr[min_idx] = arr[min_idx], arr[i]return arr

优点:

  • 实现简单,无需额外的内存空间。
  • 适用于数据量较小的情况。

缺点:

  • 时间复杂度为 O(n²),效率较低。
  • 不稳定排序,可能破坏相同元素的相对顺序。

3. 插入排序(Insertion Sort)

工作原理

插入排序通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。类似于扑克牌的排序方式。
在这里插入图片描述

实现步骤

  1. 从第二个元素开始,假设第一个元素为已排序部分。
  2. 取未排序部分的第一个元素,将其插入到已排序部分的适当位置。
  3. 重复上述过程,直到整个列表有序。

Python 实现

def insertion_sort(arr):for i in range(1, len(arr)):key = arr[i]j = i-1while j >=0 and key < arr[j]:arr[j+1] = arr[j]j -= 1arr[j+1] = keyreturn arr

优点:

  • 实现简单,效率较高,对于少量数据或基本有序的数据效果不错。
  • 稳定排序,保持相同元素的相对位置。

缺点:

  • 最坏情况下时间复杂度为 O(n²)。
  • 对于大规模数据排序效率低下。

4. 归并排序(Merge Sort)

工作原理

归并排序采用分治法,将数组分成两半,分别进行排序后再合并。其核心在于有效地将两个有序数组合并成一个有序数组。

体验最新GPT系列模型、支持自定义助手、文件上传等功能:ChatMoss & ChatGPT-AI中文版
在这里插入图片描述

实现步骤

  1. 如果数组长度小于等于1,直接返回。
  2. 将数组分成两半,分别对左右两部分进行归并排序。
  3. 合并两部分,生成有序的数组。

Python 实现

def merge_sort(arr):if len(arr) <=1:return arrmid = len(arr)//2left = merge_sort(arr[:mid])right = merge_sort(arr[mid:])return merge(left, right)def merge(left, right):merged = []i=j=0while i<len(left) and j<len(right):if left[i] < right[j]:merged.append(left[i])i+=1else:merged.append(right[j])j+=1merged.extend(left[i:])merged.extend(right[j:])return merged

优点:

  • 时间复杂度稳定为 O(n log n)。
  • 稳定排序,保持相同元素的相对位置。
  • 适用于大规模数据。

缺点:

  • 需要额外的内存空间,空间复杂度为 O(n)。

5. 快速排序(Quick Sort)

工作原理

快速排序同样采用分治策略,通过选择一个“基准”元素,将数组分成两部分,一部分小于基准元素,另一部分大于基准元素,然后递归排序两部分。
在这里插入图片描述

实现步骤

  1. 选择数组中的一个元素作为基准(通常选择第一个元素)。
  2. 重新排列数组,将小于基准的元素放到左边,大于基准的元素放到右边。
  3. 递归对左右两部分进行快速排序。

Python 实现

def quick_sort(arr):if len(arr) <=1:return arrpivot = arr[len(arr)//2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quick_sort(left) + middle + quick_sort(right)

优点:

  • 平均时间复杂度为 O(n log n),表现优异。
  • 不需要额外的内存空间(原地排序实现时)。
  • 通常比其他 O(n log n) 算法更快,尤其在实践中表现良好。

缺点:

  • 最坏情况下时间复杂度为 O(n²),如已排序数据。
  • 不稳定排序,可能破坏相同元素的相对位置。

6. 堆排序(Heap Sort)

工作原理

堆排序利用堆这种数据结构,首先将数组构建成一个最大堆(或最小堆),然后依次将堆顶元素(最大或最小)移到数组末尾,调整堆,重复此过程直到整个数组有序。
在这里插入图片描述

实现步骤

  1. 将数组构建成一个最大堆。
  2. 将堆顶元素与数组末尾元素交换,缩小堆的范围。
  3. 对堆顶进行堆调整,保持堆性质。
  4. 重复步骤2和3,直到堆的范围为1。

Python 实现

def heapify(arr, n, i):largest = il = 2*i +1r = 2*i +2if l < n and arr[l] > arr[largest]:largest = lif r < n and arr[r] > arr[largest]:largest = rif largest !=i:arr[i], arr[largest] = arr[largest], arr[i]heapify(arr, n, largest)def heap_sort(arr):n = len(arr)for i in range(n//2 -1, -1, -1):heapify(arr, n, i)for i in range(n-1, 0, -1):arr[i], arr[0] = arr[0], arr[i]heapify(arr, i, 0)return arr

优点:

  • 时间复杂度为 O(n log n)。
  • 不需要额外的内存空间(原地排序)。
  • 对于大规模数据表现稳定。

缺点:

  • 通常比快速排序慢,常数因子较大。
  • 不稳定排序,可能破坏相同元素的相对位置。

7. 计数排序(Counting Sort)

工作原理

计数排序是一种稳定的线性时间排序算法,适用于元素范围较小的整数排序。它通过统计每个元素出现的次数,计算元素的位置,最后构建有序数组。

体验最新GPT系列模型、支持自定义助手、文件上传等功能:ChatMoss & ChatGPT-AI中文版
在这里插入图片描述

实现步骤

  1. 找到待排序数组的最大值和最小值。
  2. 创建一个计数数组,统计每个元素的出现次数。
  3. 计算计数数组的前缀和,确定每个元素在有序数组中的位置。
  4. 构建有序数组,确保稳定性。

Python 实现

def counting_sort(arr):if not arr:return arrmax_val = max(arr)min_val = min(arr)range_of_elements = max_val - min_val +1count = [0]*range_of_elementsfor num in arr:count[num - min_val] +=1for i in range(1, len(count)):count[i] += count[i-1]output = [0]*len(arr)for num in reversed(arr):output[count[num - min_val] -1] = numcount[num - min_val] -=1return output

优点:

  • 时间复杂度为 O(n + k),其中 k 是元素的范围。
  • 稳定排序,保持相同元素的相对顺序。

缺点:

  • 只能用于整数排序,且元素范围较小。
  • 需要额外的内存空间,尤其当元素范围较大时。

8. 基数排序(Radix Sort)

工作原理

基数排序是一种非比较型排序算法,通过将元素按位(如个位、十位等)进行多次排序,实现整体有序。常结合计数排序作为子过程。
在这里插入图片描述

实现步骤

  1. 确定元素的最大位数。
  2. 从最低位开始,对所有元素进行稳定排序(如使用计数排序)。
  3. 重复上述过程,直到所有位数排序完成。

Python 实现

def counting_sort_for_radix(arr, exp):n = len(arr)output = [0]*ncount = [0]*10for num in arr:index = num//expcount[index %10] +=1for i in range(1,10):count[i] += count[i-1]for num in reversed(arr):index = num//expoutput[count[index %10] -1] = numcount[index %10] -=1return outputdef radix_sort(arr):if not arr:return arrmax_val = max(arr)exp =1while max_val//exp >0:arr = counting_sort_for_radix(arr, exp)exp *=10return arr

优点:

  • 时间复杂度为 O(d*(n + k)),d 是位数,k 是基数。
  • 稳定排序,保持相同元素的相对顺序。
  • 适用于大规模数据和大位数整数排序。

缺点:

  • 只能用于整数排序,或可以拆分为位进行排序的对象。
  • 需要额外的内存空间,尤其是基数较大时。

9. 桶排序(Bucket Sort)

工作原理

桶排序将元素分到多个桶中,每个桶内部再采用其他排序算法排序,最后将所有桶中的元素按顺序合并。适用于元素均匀分布的情况。
在这里插入图片描述

实现步骤

  1. 确定桶的数量和范围。
  2. 将每个元素分配到对应的桶中。
  3. 对每个桶内部进行排序(如使用插入排序)。
  4. 按顺序合并所有桶中的元素,得到有序数组。

Python 实现

def bucket_sort(arr):if not arr:return arrbucket_count = 10min_val = min(arr)max_val = max(arr)range_val = (max_val - min_val)/bucket_countbuckets = [[] for _ in range(bucket_count)]for num in arr:index = int((num - min_val)/range_val)if index == bucket_count:index -=1buckets[index].append(num)for bucket in buckets:insertion_sort(bucket)sorted_arr = []for bucket in buckets:sorted_arr.extend(bucket)return sorted_arr

10. 更多实用文章

【IDER、PyCharm】免费AI编程工具完整教程:ChatGPT Free - Support Key call AI GPT-o1 Claude3.5

【VScode】VSCode中的智能编程利器,全面揭秘ChatMoss & ChatGPT中文版

【OpenAI】获取OpenAI API Key的多种方式全攻略:从入门到精通,再到详解教程!!

11. 结语

通过这篇详尽的排序算法教程,希望能帮助你在编程学习和实际项目中游刃有余地应用各种排序技术,提升整体编程技能与算法素养。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/62091.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络协议之DNS

一、DNS概述 域名系统&#xff08;Domain Name System&#xff0c;缩写&#xff1a;DNS&#xff09;是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便地访问互联网。DNS使用TCP和UDP端口53&#xff0c;通过递归查询请求的方式来…

Z-score标准化简单理解

目录 归一化解决量纲问题 一个组里排名第一的特征是100.另一个里排名第一的特征是10,不进行归一化两组合并后特征偏向1组; 归一化后两组特征都会体现出来 Z-score标准化 Z-score标准化举例说明 归一化解决量纲问题 一个组里排名第一的特征是100.另一个里排名第一的特征…

常用docker应用部署,wordpress、mysql、tomcat、nginx、redis

案例一、 wordpress 创建网络 docker network create wordpress-network创建容器 docker volume create --name mariadb_data docker run -d --name mariadb --restartalways \-p 3306:3306 \--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORDyes \--env ALLOW_EMPTY_PASSWORDyes \--…

【PyTorch】(基础三)---- 图像读取和展示

图像读取和展示 pytorch本身并不提供图像的读取和展示功能&#xff0c;利用pytorch执行计算机视觉任务的时候&#xff0c;通常是利用opencv等工具先进行图像处理&#xff0c;然后将结果转化成tensor类型传递给pytorch&#xff0c;在pytorch执行之后&#xff0c;也可以将tensor…

快速理解微服务中Ribbon的概念

一.基本概念 1.在微服务架构中&#xff0c;Ribbon 是一个客户端负载均衡器&#xff0c;用于控制服务间的通信方式。 2.Ribbon 是一个开源的库&#xff0c;最早由 Netflix 开发&#xff0c;用于实现客户端负载均衡。 3.Ribbon 主要解决的是在微服务架构中&#xff0c;多个服务…

将VSCode设置成中文语言环境

目录 VSCode默认是英文语言环境&#xff0c;这对于像我这种英语比较菜的人来说不是那么友好 另外也习惯了用中文&#xff0c;所以接下来介绍下如何将VSCode设置成中文语言环境。 1、打开VSCode软件&#xff0c;按快捷键【CtrlShiftP】 2、在弹出的搜索框中输入【configure l…

Diffusion异常检测相关论文及代码整理

扩散模型&#xff08;Diffusion Models&#xff09;是一种生成模型&#xff0c;广泛用于图像生成、文本生成等领域。在异常检测任务中&#xff0c;扩散模型也可以被用来识别和检测异常数据点。该文章对近几年利用扩散模型进行异常检测的文章进行了整理&#xff1a; 2024 1. A…

深入了解决策树---机器学习中的经典算法

引言 决策树&#xff08;Decision Tree&#xff09;是一种重要的机器学习模型&#xff0c;以直观的分层决策方式和简单高效的特点成为分类和回归任务中广泛应用的工具。作为解释性和透明性强的算法&#xff0c;决策树不仅适用于小规模数据&#xff0c;也可作为复杂模型的基石&…

蓝桥杯c++算法秒杀【6】之动态规划【下】(数字三角形、砝码称重(背包问题)、括号序列、异或三角:::非常典型的必刷例题!!!)

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! ! &#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 动态规划 三、括号序列 【问题描述】 给定一个括号序列&#xff0c;要求尽可能少地添加若干括号使得括号序列变得合…

LLM PPT Translator

LLM PPT Translator 引言Github 地址UI PreviewTranslated Result Samples 引言 周末开发了1个PowerPoint文档翻译工具&#xff0c;上传PowerPoint文档&#xff0c;指定想翻译的目标语言&#xff0c;通过LLM的能力将文档翻译成目标语言的文档。 Github 地址 https://github.…

OpenTK 实现三维空间模型仿真详解

文章目录 一、创建渲染窗口与初始化 OpenGL二、三维模型加载三、渲染管线搭建四、模型渲染与变换五、交互与事件处理一、创建渲染窗口与初始化 OpenGL 继承 GameWindow:   构建自定义类使其继承自 GameWindow,该类内部封装了诸多窗口管理以及渲染循环逻辑,为后续渲染工作…

为什么DDoS防御很贵?

分布式拒绝服务攻击&#xff08;DDoS攻击&#xff09;是一种常见的网络安全威胁&#xff0c;通过大量恶意流量使目标服务器无法提供正常服务。DDoS防御是一项复杂且昂贵的服务&#xff0c;本文将详细探讨为什么DDoS防御如此昂贵&#xff0c;并提供一些实用的代码示例和解决方案…

三格电子—EtherNet IP转Modbus RTU网关

EtherNet/IP转Modbus RTU网关 SG-EIP-MOD-210 产品用途 SG-EIP-MOD-210网关可以实现将Modbus接口设备连接到 EtherNet/IP网络中。用户不需要了解具体的Modbus和 EtherNet/IP协议即可实现将Modbus设备挂载到 EtherNet/IP接口的PLC上&#xff0c;并和Modbus设备进行数据交互。拓…

【计算机网络】核心部分复习

目录 交换机 v.s. 路由器OSI七层更实用的TCP/IP四层TCPUDP 交换机 v.s. 路由器 交换机-MAC地址 链接设备和设备 路由器- IP地址 链接局域网和局域网 OSI七层 物理层&#xff1a;传输设备。原始电信号比特流。数据链路层&#xff1a;代表是交换机。物理地址寻址&#xff0c;交…

AIGC与SEO:如何提升网站流量

前言 随着互联网的不断发展&#xff0c;网站流量已经成为评估一个网站成功与否的关键指标之一。而在提升网站流量的各种策略中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;无疑是最为重要且广泛应用的手段之一。近年来&#xff0c;人工智能生成内容&#xff08;AIGC&…

前端网络请求:从 XMLHttpRequest 到 Axios

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Vue篇专栏内容:前端网络请求&#xff1a;从 XMLHttpRequest 到 Axios 前言 在网络应用中&#xff0c;前后端的数据…

计算机毕业设计Python+大模型美食推荐系统 美食可视化 美食数据分析大屏 美食爬虫 美团爬虫 机器学习 大数据毕业设计 Django Vue.js

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

解决登录Google账号遇到手机上Google账号无法验证的问题

文章目录 场景小插曲解决方案总结 场景 Google账号在新的设备上登录的时候&#xff0c;会要求在手机的Google上进行确认验证&#xff0c;而如果没有安装Google play就可能出现像我一样没有任何弹框&#xff0c;无法实现验证 小插曲 去年&#xff0c;我在笔记本上登录了Googl…

Element UI 打包探索【2】

目录 第三个命令 第四个命令 第五个命令 第六个命令 第七个命令 cross-env BABEL_ENV babel 第八个命令 总结 书&#x1f4da;接上文Element UI 打包探索【1】我们继续来看 第三个命令 "lint": "eslint src/**/* test/**/* packages/**/* build/**/* …

二进制与网络安全的关系

二进制与网络安全的关系 声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以…