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

Python排序算法揭秘:冒泡、插入、选择与快速排序的艺术

在这个信息爆炸的时代,数据处理变得尤为重要。作为数据处理的基础,排序算法无疑是编程中的核心技能之一。无论是处理简单的数组还是复杂的数据结构,掌握几种高效的排序算法都是必不可少的。本文将带你深入了解四种经典的排序算法——冒泡排序、插入排序、选择排序以及快速排序,并通过Python语言实现这些算法,展示它们在实际项目中的应用。

引言

排序算法不仅是一种技术手段,更是理解数据组织方式的重要途径。它帮助我们更好地理解和操作数据集,特别是在大数据分析、数据库管理和算法优化等领域发挥着关键作用。本篇博客将从零开始,逐步解析每种算法的工作原理、效率特点及其适用场景,力求让每一位读者都能从中学到有价值的知识。

基础语法介绍

冒泡排序

冒泡排序是最直观的排序方法之一。其基本思想是重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复进行的,直到没有再需要交换,也就是说该数列已经排序完成。

def bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arr

插入排序

插入排序通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。这种方法简单易懂,但效率较低,适用于小型数据集或部分已排序的数据。

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

选择排序

选择排序也是一种简单直观的比较排序算法。它的基本思想是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

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

快速排序

快速排序使用分治策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。其关键在于如何选择基准值,并通过一趟排序将待排记录分割成独立的两部分,其中一部分的所有记录都比另一部分的所有记录都要小,然后分别对这两部分记录继续进行排序,以达到整个序列有序。

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)

基础实例

假设我们有一个由随机整数组成的列表[3, 6, 1, 8, 4, 5],现在需要将其从小到大排序。

arr = [3, 6, 1, 8, 4, 5]print("原始数组:", arr)bubble_sorted = bubble_sort(arr.copy())
print("冒泡排序结果:", bubble_sorted)insertion_sorted = insertion_sort(arr.copy())
print("插入排序结果:", insertion_sorted)selection_sorted = selection_sort(arr.copy())
print("选择排序结果:", selection_sorted)quick_sorted = quick_sort(arr.copy())
print("快速排序结果:", quick_sorted)

进阶实例

在实际开发中,排序算法可能面临更复杂的挑战,例如需要根据特定条件(如日期、字符串长度等)对对象进行排序。这里我们以一个简单的例子来说明如何自定义排序规则。

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f"{self.name} ({self.age})"people = [Person("Alice", 25),Person("Bob", 20),Person("Carol", 30)
]def custom_sort(person):return person.agesorted_people = sorted(people, key=custom_sort)
for person in sorted_people:print(person)

实战案例

在某电商网站的商品推荐系统中,需要根据用户的购买历史、浏览记录等多个因素综合评分后对商品进行排序展示。这里可以采用快速排序算法结合权重计算的方式,实现高效且个性化的商品排序。

def recommend_products(history, products):# 假设history是一个用户的历史购买记录# products是一个商品列表,每个商品都有id、名称、类别等属性# 此处省略了具体评分逻辑,仅演示排序过程weighted_products = []for product in products:score = calculate_score(history, product)  # 模拟评分函数weighted_products.append((product, score))# 使用快速排序按评分降序排列sorted_products = quick_sort(weighted_products, key=lambda x: x[1], reverse=True)# 返回排序后的商品ID列表return [product[0].id for product in sorted_products]# 示例调用
history = [101, 102, 103]  # 用户历史购买记录
products = [Product(100, "Product A", "Category 1"),Product(101, "Product B", "Category 2"),Product(102, "Product C", "Category 3")
]
recommended = recommend_products(history, products)
print(recommended)

扩展讨论

排序算法的选择往往取决于具体的应用场景。例如,在处理大规模数据时,快速排序因其平均时间复杂度为O(n log n)而成为首选;而在处理小规模数据或部分已排序的数据时,则可以选择插入排序,因为它在这些情况下表现更好。此外,还应考虑算法的空间复杂度、稳定性等因素。总之,没有一种算法能够适应所有情况,合理选择合适的排序算法对于提高程序性能至关重要。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于Prometheus和Grafana的现代服务器监控体系构建
  • 艾默生电源维修ASTEC电源模块MP4-2Q-1E-4EE-0N
  • VmWare安装虚拟机保姆级教程(centos7,虚拟机网络设置,虚拟机桌面显示)
  • 高频 SQL 50 题(基础版)| 570. 至少有5名直接下属的经理
  • cocos creator 集成ffmpeg
  • VideoFileClip 切割视频
  • 《家庭无线网络覆盖项目》
  • python 实现similarity search相似性搜索算法
  • SupplierbasicController
  • Android 点击其他组件让输入框失去焦点
  • 创意实现!在uni-app小程序商品详情页轮播中嵌入视频播放功能
  • 苹果更新过时产品:三款 Mac 成“古董”,九款 Mac 彻底“停产”
  • exebios提取工具通用exebios分离工具exe转编程器bios文件软件bios文件解密提取工具exe原厂bios提取烧录器bios芯片文件工具
  • Navicat Premium Lite 免费版 | 数据库连接类型简介
  • 如何更新Oracle表 LONG型的大文本学习
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • Angular4 模板式表单用法以及验证
  • canvas 五子棋游戏
  • CAP 一致性协议及应用解析
  • Docker 笔记(2):Dockerfile
  • es6
  • MD5加密原理解析及OC版原理实现
  • Next.js之基础概念(二)
  • rabbitmq延迟消息示例
  • Swoft 源码剖析 - 代码自动更新机制
  • Vue全家桶实现一个Web App
  • 对象引论
  • 排序(1):冒泡排序
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 微服务框架lagom
  • 我的zsh配置, 2019最新方案
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 一个SAP顾问在美国的这些年
  • 主流的CSS水平和垂直居中技术大全
  • puppet连载22:define用法
  • python最赚钱的4个方向,你最心动的是哪个?
  • 阿里云ACE认证之理解CDN技术
  • 组复制官方翻译九、Group Replication Technical Details
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (C语言)逆序输出字符串
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (函数)颠倒字符串顺序(C语言)
  • (十)c52学习之旅-定时器实验
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • @RestController注解的使用
  • @SpringBootConfiguration重复加载报错
  • [ C++ ] STL---仿函数与priority_queue
  • [ACTF2020 新生赛]Upload 1