【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.rhkb.cn/news/478958.html

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

相关文章

计算机毕业设计Hadoop+Spark音乐推荐系统 音乐预测系统 音乐可视化大屏 音乐爬虫 HDFS hive数据仓库 机器学习 深度学习 大数据毕业设计

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

深入理解 Java 基本语法之运算符

&#xff08;一&#xff09;研究背景 在 Java 编程中&#xff0c;运算符是处理数据和变量的基本工具&#xff0c;掌握各种运算符的使用方法对于提高编程效率至关重要。 &#xff08;二&#xff09;研究目的 深入理解 Java 基础运算符的概念、分类和作用&#xff0c;通过具体…

【微服务】 Eureka和Ribbon

一、Eureka 服务调用出现的问题&#xff1a;在远程调用另一个服务时&#xff0c;我们采用的解决办法是发送一次http请求&#xff0c;每次环境的变更会产生新的地址&#xff0c;所以采用硬编码会出现很多麻烦&#xff0c;并且为了应对并发问题&#xff0c;采用分布式部署&#…

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

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

QT QToolButton控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…

[SWPUCTF 2021 新生赛]error

[SWPUCTF 2021 新生赛]error 报错注入&#xff1a;?idand updatexml(1,concat(0x7e,database(),0x7e),1) -- 爆出了数据库名称 test_db 爆表名&#xff1a;?idand updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_sc…

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

一.基本概念 定义&#xff1a; 在微服务架构中&#xff0c;Spring Cloud Gateway 是一个用于API网关的框架&#xff0c;它是一个基于 Spring Framework 的高效、可扩展的路由器和反向代理&#xff0c;它能够将外部请求转发到适当的微服务&#xff0c;并提供一些与请求处理相关…

【消息序列】详解(7):剖析回环模式--设备测试的核心利器

目录 一、概述 1.1. 本地回环模式 1.2. 远程环回模式 二、本地回环模式&#xff08;Local Loopback mode&#xff09; 2.1. 步骤 1&#xff1a;主机进入本地环回模式 2.2. 本地回环测试 2.2.1. 步骤 2a&#xff1a;主机发送HCI数据包并接收环回数据 2.2.2. 步骤 2b&…

GCP Dataproc有什么特点,有什么最佳实践

Google Cloud Dataproc 是一个完全托管的 Apache Hadoop 和 Apache Spark 服务&#xff0c;旨在快速处理大数据工作负载。以下是 Dataproc 的一些主要特点和最佳实践&#xff1a; 特点 托管服务&#xff1a;Dataproc 是一个完全托管的服务&#xff0c;用户无需管理基础设施&…

sunshine和moonlight串流网络丢失帧高的问题(局域网)

注&#xff1a;此贴结果仅供参考 场景环境&#xff1a;单身公寓 路由器&#xff1a;2016年的路由器 开始&#xff1a;电脑安装sunshine软件&#xff0c;手机安装moonlight软件开始串流发现网络丢失帧发现巨高 一开始怀疑就是路由器问题&#xff0c;因为是局域网&#xff0c;而…

STL容器1

STL容器1 1.1 vector1.2 set1.3 map 1.1 vector vector的优点&#xff1a; 1.动态大小调整‌&#xff1a;vector可以根据需要动态地调整大小&#xff0c;自动分配和释放内存&#xff0c;确保在添加或删除元素时实现高效的内存管理‌ 2.连续存储‌&#xff1a;vector的元素在内存…

第六届国际科技创新学术交流大会暨新能源科学与电力工程国际(NESEE 2024)

重要信息 会议官网&#xff1a;nesee.iaecst.org 会议时间&#xff1a;2024年12月6-8日 会议地点&#xff1a; 中国-广州&#xff08;越秀国际会议中心) 大会简介 新能源科学与电力工程国际学术会议&#xff08;NESEE 2024&#xff09;作为第六届国际科技创新学术交流大会分…

RL78/G15 Fast Prototyping Board Arduino IDE 平台开发过程

这是一篇基于RL78/G15 Fast Prototyping Board的Arduino IDE开发记录 RL78/G15 Fast Prototyping Board硬件简介&#xff08;背景&#xff09;基础测试&#xff08;方法说明/操作说明&#xff09;开发环境搭建&#xff08;方法说明/操作说明代码结果&#xff09;Arduino IDE RL…

visionpro实践项目(一)

1.需求&#xff1a;测量零件的宽度。 2.解决思路&#xff1a;使用模板匹配工具先匹配到零件&#xff0c;使用卡尺工具测量宽度&#xff0c;使用标签工具显示宽度信息。 3.步骤&#xff1a; 导入CogPMAlignTool工具&#xff0c;训练模板&#xff0c;实现模板匹配功能。 导入卡…

Scala习题

姓名&#xff0c;语文&#xff0c;数学&#xff0c;英语 张伟&#xff0c;87&#xff0c;92&#xff0c;88 李娜&#xff0c;90&#xff0c;85&#xff0c;95 王强&#xff0c;78&#xff0c;90&#xff0c;82 赵敏&#xff0c;92&#xff0c;88&#xff0c;91 孙涛&#xff0c…

mvn-mac操作小记

1.安装brew 如果报错&#xff0c;Warning: /opt/homebrew/bin is not in your PATH. vim ~/.zshrc&#xff0c;最后一行追加 export PATH“/opt/homebrew/bin:$PATH” source ~/.zshrc 2.安装brew install maven mvn -version查看路径 Maven home: /opt/homebrew/Cellar/mav…

银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法

银河麒麟桌面系统——桌面鼠标变成x&#xff0c;窗口无关闭按钮的解决办法 1、支持环境2、详细操作说明步骤1&#xff1a;用root账户登录电脑步骤2&#xff1a;导航到kylin-wm-chooser目录步骤3&#xff1a;编辑default.conf文件步骤4&#xff1a;重启电脑 3、结语 &#x1f49…

路由器中继与桥接

一 . 背景 现在的路由器大多数已经开始支持多种网络连接模式&#xff0c;以下将以TP-Link迷你无线路由器为例进行展开介绍。在TP-Link迷你无线路由器上一般有AP&#xff08;接入点&#xff09;模式&#xff0c;Router&#xff08;无线路由&#xff09;模式&#xff0c;Repeate…

基于springboot的县市级土地使用监控系统的设计与实现

文末获取本系统&#xff08;程序源码数据库调试部署开发环境&#xff09;文末可获取&#xff0c;系统界面在最后面。 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的…

Java【多线程】(1)进程与线程

目录 1.前言 2.正文 2.1什么是进程 2.2PCB&#xff08;进程控制块&#xff09; 2.2.1进程id 2.2.2内存指针 2.2.3文件描述符表 2.2.4进程状态 2.2.4.1就绪状态 2.2.4.2阻塞状态 2.2.5进程优先级 2.2.6进程上下文 2.2.7进程的记账信息 2.3CPU操作进程的方法 2.4什…