常用的排序算法及对比

1. 选择排序(Selection Sort)

算法思想与理论推导

  • 基本思想:
    每次从待排序数组中选择最小(或最大)的元素,将它与当前序列的起始位置交换,逐步将整个数组排序。

  • 推导过程:
    设数组长度为 n,第一次遍历需要扫描 n 个元素找到最小值,第二次扫描 (n-1) 个元素……直到最后一个元素。
    总的比较次数约为:

    (n-1) + (n-2) + \cdots + 1 = \frac{n(n-1)}{2} = O(n^2)

算法步骤

  1. 对于下标 i 从 0 到 n-2

    • 在区间 [i, n-1] 内找到最小元素的下标 min_index

    • min_indexi,则交换元素 arr[i] 与 arr[min_index]。

时间复杂度分析

  • 最坏情况: O(n²)

  • 平均情况: O(n²)

  • 空间复杂度: O(1)(原地排序)

  • 稳定性: 不稳定(因为交换可能改变相同元素的相对顺序)


2. 插入排序(Insertion Sort)

算法思想与理论推导

  • 基本思想:
    将数组分为已排序和未排序两部分,每次取未排序部分的第一个元素,在已排序部分中找到合适的位置插入,使已排序部分始终保持有序。

  • 推导过程:
    对于每个元素,最坏情况下需要和前面所有元素比较并移动位置。第 i 个元素可能需要 i 次比较和移动,总的操作次数约为:

    1 + 2 + \cdots + (n-1) = \frac{n(n-1)}{2} = O(n^2)

    当数组已经接近有序时,比较次数大大减少,时间复杂度可以达到 O(n)。

算法步骤

  1. 从数组第二个元素开始(下标 1):

    • 记当前元素为 key,从已排序部分从后向前比较,若遇到比 key 大的元素则后移。

    • 插入 key 到合适的位置。

时间复杂度分析

  • 最坏情况: O(n²)(例如数组逆序排列)

  • 平均情况: O(n²)

  • 最好情况: O(n)(例如数组已经有序)

  • 空间复杂度: O(1)

  • 稳定性: 稳定


3. 冒泡排序(Bubble Sort)

算法思想与理论推导

  • 基本思想:
    通过多次遍历数组,每次比较相邻元素,如果顺序错误则交换,将较大(或较小)的元素逐步“冒泡”到数组的一端。

  • 推导过程:
    每次遍历最多做 n-1 次比较,整个排序需要进行 n-1 次遍历,所以总的比较次数约为:

    (n-1) \times (n-1) = O(n^2)

算法步骤

  1. 重复遍历整个数组,

    • 对于每一对相邻元素,如果前者大于后者则交换。

    • 每遍历完一次后,最大的元素“浮”到数组末尾。

  2. 如果一整趟遍历没有发生交换,则排序结束。

时间复杂度分析

  • 最坏情况: O(n²)

  • 平均情况: O(n²)

  • 最好情况: 若增加标志位检测无交换情况,则最好情况为 O(n)(已经有序)

  • 空间复杂度: O(1)

  • 稳定性: 稳定


4. 归并排序(Merge Sort)

算法思想与理论推导

  • 基本思想:
    利用分治法,将数组递归地分解为两个子序列,分别排序后再将两个有序子序列合并成一个整体有序序列。

  • 推导过程:
    设 T(n) 为排序 n 个元素的时间复杂度,则:

    T(n) = 2T\left(\frac{n}{2}\right) + O(n)

    根据主定理,解得 T(n) = O(n log n)。

算法步骤

  1. 分解阶段:

    • 将数组分为两半。

    • 递归地对两半分别进行归并排序。

  2. 合并阶段:

    • 合并两个有序子数组。

时间复杂度分析

  • 最坏情况: O(n log n)

  • 平均情况: O(n log n)

  • 最好情况: O(n log n)

  • 空间复杂度: O(n)(需要额外的辅助空间用于合并)

  • 稳定性: 稳定


5. 自然合并排序(Natural Merge Sort)

算法思想与理论推导

  • 基本思想:
    利用数据中已存在的自然有序(“天然有序”的子序列或“段”),先将序列分割成若干个自然有序的段,再逐步将这些段两两归并。

  • 推导过程:
    如果输入数据已经部分有序,则自然有序的段较长,合并次数减少,最佳情况时间复杂度可接近 O(n)。
    最坏情况仍然为归并排序的情况,即当数据完全无序时,各自然段长度为 1,总共需要 O(log n) 次归并,每次归并时间 O(n),故为 O(n log n)。

算法步骤

  1. 识别自然段:

    • 扫描数组,识别连续递增(或递减)的一段作为一个“自然段”。

  2. 归并阶段:

    • 将相邻的自然段两两合并,形成新的较长的自然段。

    • 重复归并过程直到整个数组有序。

时间复杂度分析

  • 最坏情况: O(n log n)

  • 平均情况: O(n log n)

  • 最好情况: 如果数组整体有序,识别出一个自然段,时间复杂度 O(n)

  • 空间复杂度: O(n)(归并时需要辅助数组)

  • 稳定性: 稳定


6. 快速排序(Quick Sort)

算法思想与理论推导

  • 基本思想:
    利用分治策略选择一个“基准”(这里取第一个元素),将数组分成两部分:左边所有元素均小于基准,右边所有元素均大于基准,然后对这两部分递归进行排序。

  • 推导过程:
    设 T(n) 为排序 n 个元素的时间复杂度,则:

    T(n) = T(k) + T(n-k-1) + O(n)

    其中 k 表示划分后左侧子数组的大小。

    • 平均情况: 当每次划分较为均匀(大致各半),有 T(n) = 2T(n/2) + O(n),解得 T(n) = O(n log n)

    • 最坏情况: 当划分极不均匀(如数组已排序,且始终选择最小或最大元素作为基准),有 T(n) = T(n-1) + O(n),解得 T(n) = O(n²)。

算法步骤

  1. 选择基准:

    • 选择第一个元素作为基准。

  2. 分区操作:

    • 从数组两端向中间扫描,将比基准小的元素移到左边,比基准大的元素移到右边。

  3. 递归排序:

    • 对左右两个子数组分别进行快速排序。

时间复杂度分析

  • 最坏情况: O(n²)(例如每次划分极不均匀)

  • 平均情况: O(n log n)

  • 最好情况: O(n log n)

  • 空间复杂度: O(log n)(递归调用栈空间,平均情况下)

  • 稳定性: 不稳定


算法对比

算法时间复杂度(最坏/平均/最好)空间复杂度稳定性特点与适用场景
选择排序O(n²) / O(n²) / O(n²)O(1)不稳定实现简单,但比较次数固定,不适合大规模数据排序
插入排序O(n²) / O(n²) / O(n)O(1)稳定对部分有序数据效果好,适用于小规模数据或在线排序
冒泡排序O(n²) / O(n²) / O(n)(优化版)O(1)稳定实现简单,但效率低,更多用于教学演示
归并排序O(n log n) / O(n log n) / O(n log n)O(n)稳定时间复杂度稳定,适用于大规模数据,但需要额外空间
自然合并排序O(n log n) / O(n log n) / O(n)O(n)稳定能利用已有有序序列提升效率,适合部分有序数据
快速排序O(n²) / O(n log n) / O(n log n)O(log n)(平均)不稳定平均性能优异,原地排序,适合大规模数据,但最坏情况需注意

总结

  • 简单排序(选择、插入、冒泡):
    这些算法实现简单,但时间复杂度均为 O(n²)(在最坏或平均情况下),适合数据量较小的情况。插入排序在数据部分有序时表现较好,而冒泡排序常用作教学示例。

  • 分治排序(归并、快速、自然合并):
    归并排序和快速排序均有 O(n log n) 的平均时间复杂度,其中归并排序稳定但需要额外空间,而快速排序在原地排序方面有优势。自然合并排序则利用了数据中已有的有序性,在实际应用中对于部分有序数据可获得较好性能。

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

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

相关文章

Linux基础入门:从零开始掌握Linux命令行操作

🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 🎈有没有觉得电影里的黑客🐒酷毙了?他们只用键盘⌨就能搞定一切。今天,毛毛张要带你们体验这种快感😀&…

OpenAI发布的《Addendum to GPT-4o System Card: Native image generation》文件的详尽笔记

Native_Image_Generation_System_Card 文件基本信息 文件名称:《Addendum to GPT-4o System Card: Native image generation》发布机构:OpenAI发布日期:2025年3月25日主要内容:介绍GPT-4o模型中新增的原生图像生成功能&#xff…

5.02 WPF的 Combox、ListBox,slider、ProgressBar使用

1. 关于Combox\ListBox使用: 1.1 内容绑定有两种方法, 优先使用方法1,因为列表变化的时候,Combox会自动显示新的内容。而方法2并不会实时更新。 方法1:使用DataContext this.comboBox1.DisplayMemberPath "na…

《孟婆汤的SHA-256加密》

点击下面图片带您领略全新的嵌入式学习路线 🔥爆款热榜 88万阅读 1.6万收藏 文章目录 **第一章:黄泉路上的数据风暴****第二章:碱基对的非对称加密****第三章:RAFT协议暴动事件****第四章:灵魂分叉与硬重放****终章&…

SpringBoot事务管理(四)

记录几条SpringBoot事务管理中踩过的坑及解决办法: 1. 自调用问题 问题描述 在同一个类中,一个非事务方法调用另一个有 Transactional 注解的事务方法,事务不会生效。因为 Spring 的事务管理是基于 AOP 代理实现的,自调用时不会…

HTTP 1.1长连接问题

在长连接问题上,HTTP 1.1与HTTP 1.0还是有所区别的。 下面一起来看看: HTTP 1.1 支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个 TCP 连接上可以传送多个 HTTP 请求…

鸿蒙应用元服务开发-Account Kit概述

Account Kit(华为账号服务)提供简单、快速、安全的登录功能,让用户快捷地使用华为账号登录元服务。用户授权后,Account Kit可提供头像、手机号码等信息,帮助元服务更了解用户。Account Kit提供的SampleCode示例工程体现…

IP综合实验

1.配置eth-trunk进行绑定 [LSW1]interface Eth-Trunk 0 [LSW1-Eth-Trunk0]q [LSW1]interface g0/0/2 [LSW1-GigabitEthernet0/0/2]eth-trunk 0 [LSW1-GigabitEthernet0/0/2]int g0/0/3 [LSW1-GigabitEthernet0/0/3]eth-trunk 0 [LSW1-GigabitEthernet0/0/3]display et…

SAP 学习笔记 - 系统移行业务 - MALSY(由Excel 移行到SAP 的收费工具)

以前有关移行,也写过一些文章,比如 SAP 学习笔记 - 系统移行业务 - Migration cockpit工具 - 移行Material(品目)-CSDN博客 SAP 学习笔记 - 系统移行业务 - Migration cockpit工具2 - Lot导入_sap cockpit-CSDN博客 SAP学习笔记…

二叉树搜索树与双向链表

一:题目 二:思路 把二叉搜索树的值升序的打印出来,中序打印即可,但是此题不仅仅是有序的打印出二叉搜索树的值,而是要将其的结构也改变了,也就是说要改变节点间的指向,让其成为一个双向链表 我…

31天Python入门——第17天:初识面向对象

你好,我是安然无虞。 文章目录 面向对象编程1. 什么是面向对象2. 类(class)3. 类的实例关于self 4. 对象的初始化5. __str__6. 类之间的关系继承关系组合关系 7. 补充练习 面向对象编程 1. 什么是面向对象 面向对象编程是一种编程思想,它将现实世界的概念和关系映…

Spring Boot中常用内嵌数据库(H2、HSQLDB、Derby)的对比,包含配置示例和关键差异总结

以下是Spring Boot中常用内嵌数据库的对比,包含配置示例和关键差异总结: 一、主流内嵌数据库对比 1. H2 数据库 特点: 支持内存模式(速度快)和文件模式(数据持久化)。支持SQL方言&#xff08…

Apache Hive和Snowflake的`CREATE VIEW`语法和功能特性整理的对比表

写一个Apache Hive中CREATE VIEW语句转换为对应Snowflake中CREATE VIEW语句的程序,现在需要一个根据功能的相似性对应的Apache HiveQL和Snowflake SQL的CREATE VIEW语句的表。 以下是基于Apache Hive的CREATE VIEW语法规则构造的所有可能合法语句实例及其功能说明&…

个人博客网站从搭建到上线教程

步骤1:设计个人网站 设计个人博客网站的风格样式,可以在各个模板网站上多浏览浏览,以便有更多设计网站风格样式的经验。 设计个人博客网站的内容,你希望你的网站包含哪些内容如你的个人基本信息介绍、你想分享的项目、你想分享的技术文档等等。 步骤2:选择开发技术栈 因…

PHP回调后门

1.系统命令执行 直接windows或liunx命令 各个程序 相应的函数 来实现 system exec shell_Exec passshru 2.执行代码 eval assert php代码 系统 <?php eval($_POST) <?php assert($_POST) 简单的测试 回调后门函数call_user_func(1,2) 1是回调的函数 2是回调…

Raspberry 树莓派 CM4模块的底板设计注意事项

1&#xff0c; 树莓派CM4底板设计 树莓派CM4模块集成了CPU&#xff0c; 存储器&#xff0c;以太网&#xff0c; 无线模块&#xff0c;电源等等&#xff0c; 大大降低了硬件设计的要求。对我们使用树莓派提供了很好的便利性。 本人近期因为项目的需要设计了一款CM4的底板&#x…

Java后端开发(十八)-- 使用JAXB,将JavaBean转换XML文本

下面是测试时的运行环境: 1.jdk8 2.Maven,可能需要需要的依赖,如下: <dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><gr…

【一起来学kubernetes】30、k8s的java sdk怎么用

Kubernetes Java SDK 是开发者在 Java 应用中与 Kubernetes 集群交互的核心工具&#xff0c;支持资源管理、服务发现、配置操作等功能。 一、主流 Java SDK 对比与选择 官方 client-java 库 特点&#xff1a;由 Kubernetes 社区维护&#xff0c;API 与 Kubernetes 原生对象严格…

PHP开发者2025生存指南

PHP&#xff0c;这个曾经被戏称为“世界上最好的语言”的脚本语言&#xff0c;依旧在网络世界占据着重要的地位。然而&#xff0c;技术发展日新月异&#xff0c;面向2025年&#xff0c;PHP开发者要想保持竞争力甚至实现职业生涯的飞跃&#xff0c;需要不断学习和提升自身技能。…

MySQL与Redis数据一致性保障方案详解

前言 在现代分布式系统中&#xff0c;MySQL和Redis的结合使用非常普遍。MySQL作为关系型数据库负责持久化存储&#xff0c;而Redis则作为高性能缓存层提升系统的响应速度。然而&#xff0c;在这种架构下&#xff0c;如何保证MySQL与Redis之间的数据一致性是一个重要的挑战。本…