七大排序算法的基本原理 - 教程

news/2025/10/20 16:25:00/文章来源:https://www.cnblogs.com/slgkaifa/p/19152981

七大排序算法的基本原理 - 教程

1.排序的概念及引用

1.1排序的概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而排序后的序列中,r[i]扔在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

内部排序:数据元素全部放在内存中的排序。

外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断在内外存之间移动数据的排序。

1.2 常见的排序算法

2.常见排序算法的实现

2.1插入排序

2.1.1基本思想

直接插入排序是一种简单的插入排序法,基本思想是:

把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,知道所有的记录插入完为止,得到一个新的有序序列。在玩扑克牌时,就用了插入排序的思想。

2.1.2 直接插入排序

当插⼊第i(i>=1)个元素时,前面的array[0],array[1],......array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],......的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。

直接插入排序的特性总结:

1.元素集合越接近有序,直接插入排序算法的时间效率越高。

2.时间复杂度:O(N^2)

3.时间复杂度:O(1),它是一种稳定的排序算法

4.稳定性:稳定

2.1.3希尔排序(缩小增量排序)

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定⼀个整数,把待排序文件中所有记录分成多个组,所有距离相同的的记录分在同⼀组内,并对每⼀组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统⼀组内排好序。

希尔排序的特性总结:

1.希尔排序是对直接插入排序的优化

2.当gap>1时都是预排序,目的是让数组更接近于有序。当gap==1时,数组已经接近有序的了,这样就会很快。

2.1.3.1 希尔排序的时间复杂度计算

外层循环:O(log n)

内层循环:

希尔排序时间复杂度不好计算,因为 gap 的取值很多,导致很难去计算,因此很多书中给出的希尔排序的时间复杂度都不固定。

2.2选择排序

2.2.1基本思想

每次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,知道全部待排序的元素排完。

2.2.2直接选择排序

在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素

若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交 换

在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

直接选择排序的特性总结

1.直接选择排序思考非常好理解,但效率不是很好。实际中很少使用。

2.时间复杂度:O(N^2)

3.空间复杂度:O(1)

4.稳定性:不稳定

2.2.3堆排序

堆排序是指利用堆积树这种数据结构所涉及的一种排序算法,它是选择排序的一种。他是哦通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

例子:对数组 [4, 10, 3, 5, 1] 进行堆排序,我们以升序排序为目标,因此需要构建一个最大堆。数组 [4, 10, 3, 5, 1] 可以看作一个完全二叉树,其树形结构如下:

接着从最后一个非叶子结点向上进行"向下调整"(从10开始)该树已经是最大堆了,无需调整。

调整索引 0 (值为 4) 的子树

比较4、3、10,最大值为10,将4和10交换。

接着比较以4为跟的子树:

对应的数组为:[10, 5, 3, 4, 1]。现在这是一个最大堆,堆顶 10 是最大值。

把10和1交换,之后只考虑前4个元素,[1, 5, 3, 4]。

继续对该堆进行上述的操作。

堆排序的特性总结

1.堆排序使用堆来选数,效率就高了很多

2.时间复杂度:O(N*logN)

3.空间复杂度:O(1)

4.稳定性:不稳定

2.3交换排序

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列尾部移动,键值较小的记录向序列的前部移动。

2.3.1冒泡排序

举个例子

对数组 [5, 2, 4, 1, 3] 进行升序冒泡排序。

第 1 轮:目标是将最大值 5 移动到末尾。

  • [5, 2, 4, 1, 3] -> 比较 5 和 2,5>2,交换 -> [2, 5, 4, 1, 3]
  • [2, 5, 4, 1, 3] -> 比较 5 和 4,5>4,交换 -> [2, 4, 5, 1, 3]
  • [2, 4, 5, 1, 3] -> 比较 5 和 1,5>1,交换 -> [2, 4, 1, 5, 3]
  • [2, 4, 1, 5, 3] -> 比较 5 和 3,5>3,交换 -> [2, 4, 1, 3, 5]

结果:5 已经“冒泡”到正确位置。未排序部分为 [2, 4, 1, 3]

第 2 轮:将次大值 4 移动到未排序部分的末尾。

  • [2, 4, 1, 3, 5] -> 比较 2 和 4,2<4,不交换。
  • [2, 4, 1, 3, 5] -> 比较 4 和 1,4>1,交换 -> [2, 1, 4, 3, 5]
  • [2, 1, 4, 3, 5] -> 比较 4 和 3,4>3,交换 -> [2, 1, 3, 4, 5]

结果:4 已就位。未排序部分为 [2, 1, 3]

第 3 轮

  • [2, 1, 3, 4, 5] -> 比较 2 和 1,2>1,交换 -> [1, 2, 3, 4, 5]
  • [1, 2, 3, 4, 5] -> 比较 2 和 3,2<3,不交换。

结果:3 已就位。未排序部分为 [1, 2]

第 4 轮

  • [1, 2, 3, 4, 5] -> 比较 1 和 2,1<2,不交换。

排序完成!最终数组为 [1, 2, 3, 4, 5]

冒泡排序的特性总结

1. 冒泡排序是⼀种非常容易理解的排序

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:稳定

2.3.2快速排序

基本思想:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均子于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列 在相应位置上为止。

// 假设按照升序对array数组中[left, right)区间中的元素进⾏排序 
void QuickSort(int[] array, int left, int right) {if(right - left <= 1)return;// 按照基准值对array数组的 [left, right)区间中的元素进⾏划分 int div = partion(array, left, right);// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right) // 递归排[left, div) QuickSort(array, left, div);// 递归排[div+1, right) QuickSort(array, div+1, right);
}

将区间按照基准值划分为左右两半部分的常见方式有:

1.Hoare版

private static int partition(int[] array, int left, int right) {int i = left;int j = right;int pivot = array[left];while (i < j) {while (i < j && array[j] >= pivot) {j--;}while (i < j && array[i] <= pivot) {i++;}swap(array, i, j);}swap(array, i, left);return i;
}

2.挖坑法

private static int partition(int[] array, int left, int right) {int i = left;int j = right;int pivot = array[left];while (i < j) {while (i < j && array[j] >= pivot) {j--;}array[i] = array[j];while (i < j && array[i] <= pivot) {i++;}array[j] = array[i];}array[i] = pivot;return i;
}

3.前后指针

private static int partition(int[] array, int left, int right) {int prev = left; // 维护“小于区域”的右边界int cur = left + 1;while (cur <= right) {// 只需要判断当前元素是否小于基准值if (array[cur] < array[left]) {// 方法1:先自增,再交换swap(array, ++prev, cur);// 或者使用方法2:分开写,逻辑更清晰// prev++;// swap(array, prev, cur);}cur++;}// 将基准值放到“小于区域”的右边swap(array, prev, left);return prev;
}

2.3.3快速排序优化

1.三数取中法选key

2.递归到小的子区间时,可以考虑使用插入排序

2.3.4快速排序非递归

void quickSortNonR(int[] a, int left, int right) {Stack st = new Stack<>();st.push(left);st.push(right);while (!st.empty()) {right = st.pop();left = st.pop();if(right - left <= 1)continue;int div = PartSort1(a, left, right);// 以基准值为分割点,形成左右两部分:[left, div) 和 [div+1, right) st.push(div+1);st.push(right);st.push(left);st.push(div);}
}

2.3.3快速排序总结

1.快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫做快速排序。

2.时间复杂度:O(N*logN)

3.空间复杂度:O(logN)

4.稳定性:不稳定

2.4归并排序

2.4.1基本思想

归并排序(MERGE-SORT)是建立在归并操作上的⼀种有效的排序算法,该算法是采用分治法(Divide and Conquer)的⼀个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成⼀个有序表,称为二路归并。归并排序核心步骤:

2.4.2归并排序总结

1.归并排序的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。

2.时间复杂度:O(N*logN)。

3.空间复杂度:O(N)

4.稳定性:稳定

2.4.3海量数据的排序问题

外部排序:排序过程需要在磁盘等外部存储进行的排序

前提:内存只有1G,需要排序的数据有100G

因为内存中因为无法把所有数据全部放下,所以需要外部排序,而归并排序是最常用的外部排序

1. 先把文件切分成200份,每个512M

2. 分别对512M排序,因为内存已经可以放的下,所以任意排序方式都可以

3. 进行2路归并,同时对200份有序文件做归并过程,最终结果就有序了

3.排序算法复杂度及稳定性分析

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

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

相关文章

牛客刷题-Day15

优先队列、并查集 https://ac.nowcoder.com/acm/contest/22904?from=acdiscuss牛客刷题-Day15 今日刷题:\(1011-1015\) 1011 小A与任务 题目描述 小A手头有 \(n\) 份任务,他可以以任意顺序完成这些任务,只有完成当…

2025年青海视频号运营服务商权威推荐榜:专业内容策划与精准流量投放口碑之选

2025年青海视频号运营服务商权威推荐榜:专业内容策划与精准流量投放口碑之选 在数字经济蓬勃发展的今天,视频号作为内容传播与商业转化的重要阵地,已成为企业品牌建设与营销推广的核心渠道。青海地区依托独特的文化…

数据结构学习(1)——指针、结构体、链表(C语言) - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

LVDS硬件知识 - 指南

LVDS硬件知识 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "…

task 1 improved

task 1 improved#include <stdio.h> #include <stdlib.h> #include <time.h>#define N 5 #define N1 80 #define N2 35 int main(){int cnt;int r;//random_major,random_no;srand(time(NULL)); //n…

rhel v7 v8 local repository setting

---------v7----------- echo -e "[RHEL7-ELS]" > /etc/yum.repos.d/web.repo echo -e "name=RHEL7-ELS" >> /etc/yum.repos.d/web.repo echo -e "enabled=1" >> /etc/y…

2025 年仿石漆厂家最新推荐榜,技术实力与市场口碑深度解析,精选优质企业助力选购水包砂/冠晶石/外墙/多彩/批刮仿石漆厂家推荐

引言 当前仿石漆行业蓬勃发展,但市场品牌繁杂、产品质量良莠不齐,采购方在挑选时常常面临诸多难题。部分产品仿石效果不佳、性能不稳定,甚至存在环保隐患,不仅影响建筑外观与使用寿命,还可能危害环境与人体健康。…

wsl连接 USB 设备

连接 USB 设备2025/06/11本指南将演练使用 USB/IP 开源项目 usbipd-win 将 USB 设备连接到 WSL 2 上运行的 Linux 分发版所需的步骤。 在 Windows 计算机上配置 USB/IP 项目可以实现常见的开发者 USB 场景,例如刷写 A…

完整教程:轻量服务器创建mysql,并配置远程连接

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【完整版】vcruntime140_1.dll缺失?3步快速修复教程(含官方修复工具+系统适配指南)

当你在运行 Photoshop、Premiere、WPS 或游戏时出现“由于找不到 vcruntime140_1.dll,无法继续执行代码”的提示,不要慌。本文详细讲解 vcruntime140_1.dll 文件的作用、缺失原因,并提供三种权威修复方案:微软官方…

linux 学习平台 arm+x86 搭建 - 详解

linux 学习平台 arm+x86 搭建 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monac…

如何系统化掌握 iOS 26 App 耗电管理,多工具协作

本文聚焦 iOS 26 App 耗电管理 /能耗监控 /后台唤醒优化主题,从电量下降速率、资源占用、后台任务、文件 IO/网络访问、版本差异等维度构建监控体系。结合多工具(Xcode Instruments、KeyMob 克魔、APM平台、文件工具…

user read only folder

setfacl -R -m u:iasloguser:r-x /scb/iads/gateway/log/ setfacl -R -m d:u:iasloguser:r-x /scb/iads/gateway/log/ d:u: is default ACL getfacl /scb/iads/gateway/log/

告别重复劳动,MonkeyCode 让你的开发团队拥有永动机

告别重复劳动,MonkeyCode 让你的开发团队拥有"永动机"作为一个在代码海洋里摸爬滚打了多年的开发者,我见过太多团队陷入这样的困境:代码审查耗时耗力、新人培养成本高昂、文档更新永远滞后、重复性工作占…

cpu for rhel8 on vmware

yum install sysstat -y systemctl start sysstat systemctl enable sysstat systemctl status sysstat tuned-adm list tuned-adm profile throughput-performance tuned-adm active echo 1 second,total 3 times mps…

CentOS7安装Python3.10环境

主要步骤:依赖=>下载=>编译=>配置 依赖  常见错误没有安装相关的依赖库The necessary bits to build these optional modules were not found:  _curses  _curses_panel  _dbm  _gdbm  _lzma  …

2025 年冷库板厂家最新推荐榜:前五优质生产商盘点,含聚氨酯 / 保温 / 阻燃板企业选购指南 聚氨酯夹心板/聚氨酯保温板厂家推荐

引言2025 年国内冷链行业持续扩容,生鲜电商、医药冷链等领域对冷库板的需求呈爆发式增长,然而市场上产品质量参差不齐,部分厂商存在导热系数不达标、阻燃性能不足等问题,采购方难以精准筛选优质供应商。新版冷库节…

自主进化的AI大模型架构设想(解决大模型时效性问题):知识网络的拓扑设计 - 详解

自主进化的AI大模型架构设想(解决大模型时效性问题):知识网络的拓扑设计 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; fon…

2025 年大连 AI 品牌最新推荐排行榜:甄选懂商业重实效的实力服务商大连Ai培训/大连Ai开发/大连Ai推广公司推荐

引言 随着 AI 技术加速渗透商业场景,大连本地企业对 AI 服务的需求呈爆发式增长,但行业乱象却让企业陷入选择困境:技术与商业脱节的服务导致 AI 工具沦为 “摆设”,缺乏实战指导的培训让企业学完仍无法落地,远程服…

2025 年 MacBook / 苹果电脑清理应用程序最新推荐榜单:精选适配 macOS 系统的高性能系统优化工具

引言 随着 MacBook 等苹果电脑在工作与生活中的广泛应用,用户对系统流畅度和存储空间管理的需求愈发迫切。长期使用后,电脑易堆积缓存、冗余文件,还可能遭遇恶意软件侵扰,导致运行卡顿、存储空间告急,而 macOS 自…