Python实战开发及案例分析(7)—— 排序算法

        排序算法是计算机科学中的基础,用于将数据元素按照特定的顺序排列。Python 提供了多种方式来实现排序算法,包括内置的排序函数和手动实现各种经典排序算法。

Python 内置排序函数

Python 的内置函数 sorted() 和列表的 sort() 方法提供了高效的排序功能。这两种方法默认使用 Timsort 算法,这是一种结合了归并排序和插入排序的高效排序算法。

sorted() 函数

  sorted() 函数可以接受任何可迭代对象,并返回一个新的排好序的列表。

示例:排序一组数字和字符串

# 数字排序
numbers = [5, 2, 9, 1, 5, 6]
sorted_numbers = sorted(numbers)
print("Sorted numbers:", sorted_numbers)# 字符串排序
words = ["banana", "apple", "cherry", "date"]
sorted_words = sorted(words)
print("Sorted words:", sorted_words)
列表的 sort() 方法

        与 sorted() 不同,sort() 方法会就地排序列表,不创建新的列表。

# 就地排序
numbers = [5, 2, 9, 1, 5, 6]
numbers.sort()
print("Sorted numbers in-place:", numbers)

手动实现排序算法

        对于教学和理解排序算法的基本原理,手动实现经典排序算法是非常有用的。

插入排序

        插入排序是一种简单直观的比较排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

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# 示例使用
arr = [12, 11, 13, 5, 6]
insertion_sort(arr)
print("Array sorted using insertion sort:", arr)
快速排序

        快速排序是一种高效的排序算法,采用分治法的策略,通过一个分区操作,将原数组分为两个子数组,左边子数组的元素都比右边子数组的元素小,然后递归地排序两个子数组。

def quick_sort(arr):if len(arr) <= 1:return arrelse:pivot = 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)# 示例使用
arr = [3, 6, 8, 10, 1, 2, 1]
sorted_arr = quick_sort(arr)
print("Array sorted using quick sort:", sorted_arr)

结论

        排序算法是数据结构和算法学习的基础,对于优化数据处理和搜索算法非常重要。Python 的内置排序方法提供了高效和简单的解决方案,而手动实现这些算法则有助于深入理解其背后的原理和特点。在实际应用中,选择合适的排序算法可以根据具体需求进行,例如数据大小、数据结构的特性和所需的效率。通过这些示例,我们可以看到不同排序算法在处理相同数据时的效果和性能差异。

        继续探讨更多的排序算法,我们可以深入学习一些其他重要的经典排序算法,如归并排序和堆排序。这些算法在不同的应用场景中表现出了不同的性能优势,特别是在处理大规模数据集时。

归并排序

        归并排序是一种有效的排序算法,采用分治法的策略来实现。它将数组分割成两半,分别排序,然后将它们合并在一起。这种方法在最坏、平均和最佳情况下都提供 𝑂(𝑛log⁡𝑛)O(nlogn) 的时间复杂度。

Python 实现:        

def merge_sort(arr):if len(arr) > 1:mid = len(arr) // 2  # 找到中间位置left_half = arr[:mid]right_half = arr[mid:]merge_sort(left_half)  # 对左半部分递归排序merge_sort(right_half)  # 对右半部分递归排序i = j = k = 0# 合并两半while i < len(left_half) and j < len(right_half):if left_half[i] < right_half[j]:arr[k] = left_half[i]i += 1else:arr[k] = right_half[j]j += 1k += 1# 检查是否有剩余while i < len(left_half):arr[k] = left_half[i]i += 1k += 1while j < len(right_half):arr[k] = right_half[j]j += 1k += 1return arr# 示例使用
arr = [38, 27, 43, 3, 9, 82, 10]
sorted_arr = merge_sort(arr)
print("Array sorted using merge sort:", sorted_arr)

结论

        归并排序和堆排序提供了不同于简单排序算法(如插入排序或冒泡排序)的性能优势,尤其在处理大规模数据集时表现出更好的稳定性和效率。通过动手实现这些算法,不仅可以加深对其工作原理的理解,还可以提高解决实际排序问题的能力。在实际应用中,选择合适的排序算法可以根据数据的特性和所需的操作效率来决定。

        继续深入探讨更多高级排序算法,我们可以讨论希尔排序和计数排序。这些算法通过不同的策略来优化排序过程,适用于特定类型的数据集。

希尔排序

        希尔排序(也称为递减增量排序算法)是一种基于插入排序的算法。它首先排序间隔较远的元素,然后逐渐减少间隔距离。希尔排序比传统的插入排序更高效,因为它允许元素一次移动较远的距离。

Python 实现:

def shell_sort(arr):n = len(arr)gap = n // 2  # 初始间隔while gap > 0:for i in range(gap, n):temp = arr[i]j = i# 进行插入排序,将元素按间隔进行比较while j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempgap //= 2  # 减少间隔return arr# 示例使用
arr = [35, 33, 42, 10, 14, 19, 27, 44]
sorted_arr = shell_sort(arr)
print("Array sorted using shell sort:", sorted_arr)

计数排序

        计数排序是一种非基于比较的排序算法,适用于一定范围内的整数排序。它计算每个元素的出现次数,然后根据元素的计数来放置元素在其正确位置。计数排序是一个线性时间复杂度的排序算法,当输入的元素是 n 个在一定范围内的整数时,它非常高效。

Python 实现:

def counting_sort(arr, max_val):n = len(arr)count = [0] * (max_val + 1)  # 计数数组output = [0] * n  # 输出数组# 存储每个元素的计数for num in arr:count[num] += 1# 计数数组变形,后面的元素等于前面的元素之和for i in range(1, max_val + 1):count[i] += count[i - 1]# 反向填充目标数组,保持排序的稳定性for i in range(n - 1, -1, -1):output[count[arr[i]] - 1] = arr[i]count[arr[i]] -= 1return output# 示例使用
arr = [4, 2, 2, 8, 3, 3, 1]
max_val = max(arr)  # 找到最大值
sorted_arr = counting_sort(arr, max_val)
print("Array sorted using counting sort:", sorted_arr)

结论

        希尔排序和计数排序提供了不同的方法来处理排序问题。希尔排序通过分组和逐步细化的插入排序加快排序过程,而计数排序则完全脱离了比较排序的范畴,通过计算元素的出现频率来实现排序。这些算法在适当的场景下使用可以显著提高排序效率,如希尔排序适合中等大小的数组,而计数排序适用于有明确范围的整数数组。在实际选择排序算法时,了解数据的性质和需求是非常关键的,以确保算法的效率和适用性。

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

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

相关文章

什么?你用service调controller,那参数校验怎么办?

你好&#xff0c;我是柳岸花开。 你有没有遇到过用service调controller的场景&#xff1f;我司公有云用的微服务架构&#xff0c;私有云则用的合并完的微服务架构——一个单体&#xff0c;这就涉及到用service调controller&#xff0c;这个明显的问题是参数校验会失效&#xff…

【网络安全产品】---应用防火墙(WAF)

what Web应用防火墙&#xff08;Web Application Firewall) WAF可对网站或者App的业务流量进行恶意特征识别及防护&#xff0c;在对流量清洗和过滤后&#xff0c;将正常、安全的流量返回给服务器&#xff0c;避免网站服务器被恶意入侵导致性能异常等问题&#xff0c;从而保障…

快速了解Django:核心概念解析与实践指南

title: 快速了解Django&#xff1a;核心概念解析与实践指南 date: 2024/5/1 20:31:41 updated: 2024/5/1 20:31:41 categories: 后端开发 tags: Django核心路由系统视图系统ORM管理中间件Web框架登录装饰器 第一章&#xff1a;Django简介 背景和发展历程&#xff1a; Djan…

计算机毕业设计springboot基于vue电商抢购限时秒杀系统ch0h8

技术栈 ide工具&#xff1a;IDEA 或者eclipse 编程语言: java 数据库: mysql5.7以上版本 可选框架&#xff1a;ssmspringboot都有的 前端&#xff1a;vue.jsElementUI 详细技术&#xff1a;springbootSSMvueMYSQLMAVEN 数据库工具&#xff1a;Navicat/SQLyog都可以 开发工具 Ec…

CMakeLists.txt语法规则:部分常用命令说明四

一. 简介 前面几篇文章学习了CMakeLists.txt语法中前面几篇文章学习了CMakeLists.txt语法中部分常用命令。文章如下&#xff1a; CMakeLists.txt语法规则&#xff1a;部分常用命令说明一-CSDN博客 CMakeLists.txt语法规则&#xff1a;部分常用命令说明二-CSDN博客 CMakeLi…

【算法设计与分析】六、动态规划:(二)上机-1、地牢逃生【理论到程序】

文章目录 一、题目1、问题2、输入输出要求3、样例说明4、数据范围 二、思路1、GPT4 - fail算法解释C 实现 2、Claude3 - fail问题分析算法实现 3、个人拙见 - succeed 三、代码实现 一、题目 1、问题 用一个 nn 的矩阵表示一座地牢&#xff0c;矩阵中第 i 行第 j 列的方格的值…

力扣每日一题106:从中序与后序遍历序列构造二叉树

题目 中等 相关标签 相关企业 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postorder …

OpenCV(五) —— 人脸识别模型训练与 Windows 下的人脸识别

本文主要内容&#xff1a; 如何训练 OpenCV 的人脸识别模型如何在 Windows 下利用 OpenCV 进行人脸识别 1、概述 人脸识别需要人脸模型&#xff08;特征集合&#xff09;的支持&#xff0c;人脸定位的速度与准确度取决于模型。 OpenCV 提供了已经训练好的模型&#xff0c;无…

KAN网络认识

首先&#xff0c;这是一个基于柯尔莫哥洛夫-阿诺德表示定理的网络。这个定理指出如果函数f是定义在有界域上的多变量连续函数&#xff08;即最终要拟合的非线性函数是连续的&#xff09;&#xff0c;那么该函数就可以表示为多个单变量、加法连续函数的有线组合。 对于机器学习…

大数据BI可视化(Echarts组件)项目开发-熟悉交互API5.0

全局echarts对象 init初始化 registerTheme注册主题 var mCharts echarts.init(document.querySelector("div"), itcast)registerMap地图图表 connect 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

程序员副业项目开发支付解决方案

个人支付解决方案 让我们跳过开发环节&#xff0c;来谈谈如何变现。大部分支付方案都是为企业设计的&#xff0c;面向个人的正规支付方案相对较少。那么&#xff0c;对于那些没有注册公司的个人来说&#xff0c;怎样才能更安全地收款呢&#xff1f; 常见的几种个人收款方式 个…

OpenCV(六) —— Android 下的人脸识别

本篇我们来介绍在 Android 下如何实现人脸识别。 上一篇我们介绍了如何在 Windows 下通过 OpenCV 实现人脸识别&#xff0c;实际上&#xff0c;在 Android 下的实现的核心原理是非常相似的&#xff0c;因为 OpenCV 部分的代码改动不大&#xff0c;绝大部分代码可以直接移植到 …

ubuntu安装LVGL/lv_img_conv并在thinkphp中进行调用生成bin文件

项目需求&#xff1a;需要处理图片成为bin文件&#xff0c;并以二进制的方式传给蓝牙设备&#xff0c;当前仅介绍如何安装&#xff0c;对lvgl功能和简介不做过多描述 项目库地址&#xff1a;https://github.com/lvgl/lv_img_conv 安装过程比较简单 一&#xff0c;确保node.j…

mall-cook本地部署运行

下载源代码 https://github.com/wangyuan389/mall-cook 下载好之后解压&#xff0c;删除.github和yarn.lock&#xff0c;因为使用pnpm 启动文档部署 切换到packages\mall-cook-document&#xff0c;删除yarn.lock&#xff0c;安装依赖包pnpm install 执行pnpm dev启动文档…

C语言/数据结构——(用双链表实现数据的增删查改)

一.前言 嗨嗨嗨&#xff0c;大家好久不见&#xff01;前面我们已经通过数组实现数据的增删查改、单链表实现数据的增删查改&#xff0c;现在让我们尝试一下使用双链表实现数据的增删查改吧&#xff01; 二.正文 如同往常一样&#xff0c;对于稍微大点的项目来说&#xff0c;…

TCP与UDP协议:你应该知道的传输层协议

第一部分&#xff1a;引言与协议概述 在互联网通信的宏伟架构中&#xff0c;传输控制协议(TCP, Transmission Control Protocol)与用户数据报协议(UDP, User Datagram Protocol)如同两颗璀璨的星辰&#xff0c;各自扮演着不可或缺的角色。它们作为传输层的两大支柱&#xff0c…

推荐网站(2)今日热榜合集,看不同软件的热点事件

当我们想要看微博&#xff0c;今日头条&#xff0c;bilibili等等今日热点时&#xff0c;需要打开对应的app查看&#xff0c;但是有了这个网站我们可以看不同平台的热点消息&#xff0c;甚至京东&#xff0c;淘宝等购物软件&#xff0c;也能看到热销总榜。 链接直达&#xff1a;…

day-28 除自身以外数组的乘积

思路 利用两个空数组left&#xff08;left[i]表示nums下标从0到i的乘积&#xff09;和right&#xff08;right[i]表示nums下标从n-1到i的乘积&#xff09; 解题方法 返回数组nums[i]right[i1]*left[i-1],第一个元素和最后一个元素单独考虑 Code class Solution {public int[…

【计算机网络】计算机网络的定义和分类

一.定义 计算机网络并没有一个精确和统一的定义&#xff0c;在计算机网络发展的不同阶段&#xff0c;人们对计算机网络给出了不同的定义&#xff0c;这些定义反映了当时计算机网络技术的发展水平。 例如计算机网络早期的一个最简单定义&#xff1a;计算机网络是一些互连的、自…

c#Excel:2.写入Excel表 3.读取Excel表

--写入Excel表-- 该例首先从数据库aq中读取学生信息表staq(参考数据库章节)&#xff0c;然后将学生信息表中的数据写入Excel表格中 &#xff08;1&#xff09;在OfficeOperator类库项目的ExcelOperator类中定义索引器&#xff0c;用于获取Excel表格中的单元格&#xff0c;代码…