当前位置: 首页 > news >正文

【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. 结语

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

相关文章:

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

文章目录 1. 冒泡排序&#xff08;Bubble Sort&#xff09;2. 选择排序&#xff08;Selection Sort&#xff09;3. 插入排序&#xff08;Insertion Sort&#xff09;4. 归并排序&#xff08;Merge Sort&#xff09;5. 快速排序&#xff08;Quick Sort&#xff09;6. 堆排序&…...

【346】Postgres内核 Startup Process 通过 signal 与 postmaster 交互实现 (5)

1. Startup Process 进程 postmaster 初始化过程中, 在进入 ServerLoop() 函数之前,会先通过调用 StartChildProcess() 函数来开启辅助进程,这些进程的目的主要用来完成数据库的 XLOG 相关处理。 如: 核实 pg_wal 和 pg_wal/archive_status 文件是否存在Postgres先前是否发…...

Jmeter中的测试片段和非测试原件

1&#xff09;测试片段 1--测试片段 功能特点 重用性&#xff1a;将常用的测试元素组合成一个测试片段&#xff0c;便于在多个线程组中重用。模块化&#xff1a;提高测试计划的模块化程度&#xff0c;使测试计划更易于管理和维护。灵活性&#xff1a;可以通过模块控制器灵活地…...

利用 Jsoup 进行高效 Web 抓取与 HTML 处理

Jsoup 是一款 Java 的 HTML 解析器&#xff0c;可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API&#xff0c;可通过 DOM&#xff0c;CSS 以及类似于 JQuery 的操作方法来取出和操作数据。 官网&#xff1a;https://jsoup.org/ 中文文档&#xff1a;Jsou…...

【Java】二叉树:数据海洋中灯塔式结构探秘(上)

个人主页 &#x1f339;&#xff1a;喜欢做梦 二叉树中有一个树&#xff0c;我们可以猜到他和树有关&#xff0c;那我们先了解一下什么是树&#xff0c;在来了解一下二叉树 一&#x1f35d;、树型结构 1&#x1f368;.什么是树型结构&#xff1f; 树是一种非线性的数据结构&…...

微信小程序 WXS 的概念与基本用法教程

微信小程序 WXS 的概念与基本用法教程 引言 在微信小程序的开发中,WXS(WeiXin Script)是一种特殊的脚本语言,旨在解决小程序在逻辑处理和数据处理上的一些限制。WXS 允许开发者在小程序的 WXML 中嵌入 JavaScript 代码,以便实现更复杂的逻辑处理。本文将深入探讨 WXS 的…...

Vue.js 中 v-bind 和 v-model 的用法与异同

简介 在 Vue.js 中&#xff0c;v-bind 和 v-model 是两个非常常用且强大的指令&#xff0c;它们分别用于动态地绑定属性和实现双向数据绑定。理解这两个指令的用法和区别对于构建 Vue.js 应用至关重要。本文将详细介绍 v-bind 和 v-model 的用法&#xff0c;并探讨它们的异同。…...

K8s的水平自动扩容和缩容HPA

HPA全称是Horizontal Pod Autoscaler&#xff0c;翻译成中文是POD水平自动伸缩&#xff0c;HPA可以基于CPU利用率对replication controller、deployment和replicaset中的pod数量进行自动扩缩容&#xff08;除了CPU利用率也可以基于其他应程序提供的度量指标custom metrics进行自…...

【AI日记】24.11.26 聚焦 kaggle 比赛

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 核心工作 1 内容&#xff1a;研究 kaggle 比赛时间&#xff1a;3 小时 核心工作 2 内容&#xff1a;学习 kaggle 比赛 Titanic - Machine Learning from Disaster时间&#xff1a;4 小时备注&#xff1a;这…...

大型语言模型LLM - Finetuning vs Prompting

资料来自台湾大学李宏毅教授机器学课程ML 2023 Spring&#xff0c;如有侵权请通知下架 台大机器学课程ML 2023 Springhttps://speech.ee.ntu.edu.tw/~hylee/ml/2023-spring.php2023/3/10 课程 機器如何生成文句 内容概要 主要探讨了大型语言模型的两种不同期待及其导致的两类…...

【IEEE独立出版 | 厦门大学主办】第四届人工智能、机器人和通信国际会议(ICAIRC 2024,12月27-29日)

第四届人工智能、机器人和通信国际会议&#xff08;ICAIRC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Robotics, and Communication 重要信息 会议官网&#xff1a;www.icairc.net 三轮截稿时间&#xff1a;2024年11月30日23:59 录…...

【GPT】力量训练是什么,必要吗,有可以替代的方式吗

什么是力量训练&#xff1f; 力量训练是一种通过抵抗力&#xff08;如重量、阻力带、自身体重等&#xff09;来刺激肌肉收缩&#xff0c;从而提高肌肉力量、耐力和体积的运动形式。它包括以下常见形式&#xff1a; 自由重量训练&#xff1a;使用哑铃、杠铃、壶铃等。固定器械…...

【03】Selenium+Python 八种定位元素方法

操作元素&#xff0c;需要先查找定位到对应的元素。 查找单个元素&#xff1a;driver.find_element() 返回是一个web element 对象 查找多个元素&#xff1a;driver.find_elements() 返回是一个list对象 By 是 Selenium 中一个非常重要的类&#xff0c;用于定位网页元素。 使…...

笔记:jQuery追加js时会自动加“_时间戳“参数,导致百度统计失败

问题描述&#xff1a; $(document.createElement("script")).attr(id, baidutj).attr(src, https://hm.baidu.com/hm.js?xxx).appendTo(body); 会自动给src加_时间戳的参数&#xff1f; 问题解疑&#xff1a; 【未完待续…】 问题解决&#xff1a; 老老实实按它…...

【PyTorch】(基础二)---- 张量

张量 在 PyTorch 中&#xff0c;张量&#xff08;Tensor&#xff09;是核心数据结构&#xff0c;类似于 NumPy 中的数组&#xff0c;但具有更强的计算能力和对 GPU 的支持。 创建 从列表或数组创建 import torch# 从列表创建 tensor_from_list torch.tensor([1, 2, 3, 4])…...

充满智慧的埃塞俄比亚狼

非洲的青山 随着地球温度上升&#xff0c;贝尔山顶峰的冰川消失殆尽&#xff0c;许多野生动物移居到海拔3000米以上的高原上生活&#xff0c;其中就包括埃塞俄比亚狼。埃塞俄比亚狼是埃塞俄比亚特有的动物&#xff0c;总数不到500只&#xff0c;为“濒危”物种。 埃塞俄比亚狼…...

基于STM32设计的智能桌面暖风机(华为云IOT)

一、前言 1.1 项目开发背景 随着智能家居技术的迅猛发展&#xff0c;传统家用电器正逐步向智能化方向转型。暖风机作为冬季广泛使用的取暖设备&#xff0c;其智能化升级不仅能够提高用户的使用体验&#xff0c;还能通过物联网技术实现远程控制和数据监控&#xff0c;赋予其更…...

零基础学安全--云技术基础

目录 学习连接 前言 云技术历史 云服务 公有云服务商 云分类 基础设施即服务&#xff08;IaaS&#xff09; 平台即服务&#xff08;PaaS&#xff09; 软件即服务&#xff08;SaaS&#xff09; 云架构 虚拟化 容器 云架构设计 组件选择 基础设施即代码 集成部署…...

Spring Boot中配置Flink的资源管理

在 Spring Boot 中配置 Flink 的资源管理&#xff0c;需要遵循以下步骤&#xff1a; 添加 Flink 依赖项 在你的 pom.xml 文件中&#xff0c;添加 Flink 和 Flink-connector-kafka 的依赖项。这里以 Flink 1.14 版本为例&#xff1a; <!-- Flink dependencies --><de…...

51单片机从入门到精通:理论与实践指南入门篇(二)

续51单片机从入门到精通&#xff1a;理论与实践指南&#xff08;一&#xff09;https://blog.csdn.net/speaking_me/article/details/144067372 第一篇总体给大家在&#xff08;全局&#xff09;总体上讲解了一下51单片机&#xff0c;那么接下来几天结束详细讲解&#xff0c;从…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...

安宝特案例丨寻医不再长途跋涉?Vuzix再次以AR技术智能驱动远程医疗

加拿大领先科技公司TeleVU基于Vuzix智能眼镜打造远程医疗生态系统&#xff0c;彻底革新患者护理模式。 安宝特合作伙伴TeleVU成立30余年&#xff0c;沉淀医疗技术、计算机科学与人工智能经验&#xff0c;聚焦医疗保健领域&#xff0c;提供AR、AI、IoT解决方案。 该方案使医疗…...

运动控制--BLDC电机

一、电机的分类 按照供电电源 1.直流电机 1.1 有刷直流电机(BDC) 通过电刷与换向器实现电流方向切换&#xff0c;典型应用于电动工具、玩具等 1.2 无刷直流电机&#xff08;BLDC&#xff09; 电子换向替代机械电刷&#xff0c;具有高可靠性&#xff0c;常用于无人机、高端家电…...

OCC笔记:TDF_Label中有多个相同类型属性

注&#xff1a;OCCT版本&#xff1a;7.9.1 TDF_Label中有多个相同类型的属性的方案 OCAF imposes the restriction that only one attribute type may be allocated to one label. It is necessary to take into account the design of the application data tree. For exampl…...