常用排序算法总结

内容目录

  • 1. 选择类排序
    • 1.1 直接选择排序
    • 1.2 堆排序
  • 2. 交换类排序
    • 2.1 冒泡排序
    • 2.2 快速排序
  • 3. 插入类排序
    • 3.1 直接插入排序
    • 3.2 希尔排序
  • 4. 其它排序
    • 4.1 归并排序
    • 4.2 基数排序/桶排序

排序

在这里插入图片描述

在这里插入图片描述

1. 选择类排序

选择类排序的特征是每次从待排序集合中选择出一个最大值或者最小值。

1.1 直接选择排序

原理:两层循环,外层循环标记从哪开始遍历待排序数组,内层循环标记当前正在比较的元素。每次内层循环选出一个最小值/最大值。

ADL代码

在这里插入图片描述

复杂度

1.2 堆排序

原理:堆排序在逻辑上使用完全二叉树的结构,分为大顶堆小顶堆两类,即根结点为最大值的二叉树和根节点为最小值的二叉树。在物理结构上一般使用数组来实现完全二叉树。以大顶堆为例,对待排序数组进行排序主要需要完成两个操作:

  1. 在待排序数组上构造大顶堆。
  2. 从堆中取出最大值,并调整堆使其根节点仍然存储最大值。

可见,使用堆排序也是每次从待排序集合中选择一个最大或者最小值,因此其属于选择排序

在这里插入图片描述

那么该如何实现堆排序的这两个操作呢?

答案是:需要一个Restore操作负责:在其左右子树均已经为合法的堆的情况下,将以R为根的二叉树重建为堆

有了Restore操作之后,就可以完成初始化整个堆和从堆中选择最大值或者最小值的操作了:

  1. 初始化整个堆: 从结点floor(n/2)开始直到结点1依次遍历,对以每个结点为根的子树执行Restore操作。
  2. 从堆中选出一个最大值:将结点1与最后一个结点交换,堆的大小减一,对新的结点1执行Restore操作。

ADL代码

算法Restore(R, f, e. R)
/*R是存储完全二叉树的数组,索引从1开始;f是子树根节点索引;e是R中元素数量*/
R1.[初始化当前需要对比的子树的根]
    i <- f.
R2.[与左右子结点对比]
    // R[i]的右子结点就是R[2 * i + 1]
    // 左子节点就是R[2 * i]
	WHILE i <= e / 2 DO
    (
		IF 2 * i + 1 <= e AND R[2 * i + 1] > R[2 * i]
    		child <- 2 * i + 1.
   		ELSE child <- 2 * i.
    	
    	IF R[child] > R[i] THEN
    	(
        	R[child] <-> R[i].
            i <- child.
        )
    	ELSE
    	(
        	BREAK.
        )
	)|
    
算法HeapSort(R, n. R)
/**/
H1.[初始化堆]
    FOR i = n/2 TO 1 STEP -1 DO
    (
		Restore(R, i, n. R).
	)
H2.[堆排序]
    e <- n.
    FOR j = n TO 2 STEP -1 DO
    (
		R[1] <-> R[j].
    	e <- e - 1.
    	Restore(R, 1, e. R).
	)|

复杂度:时间复杂度O(nlogn)。空间复杂度O(1)。不稳定。

2. 交换类排序

2.1 冒泡排序

原理:两层循环,外层循环标记待排序数组的最后一个元素下标e,内层循环负责比较当前元素i与其下一个元素j:

  • 如果i > j,交换i,j。
  • 如果i <= j,什么都不做。

这样内层循环遍历到e,此时e一定存储的是从1到e中的最大元素。

ADL代码:

在这里插入图片描述

扩展:看一下对冒泡排序的改进p237。改变了最好情况下的时间复杂度。

复杂度:O(n2)。O(1)。稳定。

2.2 快速排序

原理:快速排序基于一种自顶向下分治的思想,步骤如下:

  1. 如果待排序数组为空或者只剩下一个元素,直接返回
  2. 从待排序数组中任意选取一个元素,将比这个元素小的元素交换到数组的左边,比这个元素大的元素交换到数组的右边,这样就得到了两个子数组。
  3. 分别对两个子数组进行以上操作。

可以看到,这个算法适合使用递归来实现。

算法的关键问题和步骤在于:如何高效的把小的元素交换到右边,把大的元素交换到左边?

决定算法时间复杂度的步骤是:如何从待排序数组中选择一个元素,使其尽量把原数组划分为等长的子数组

扩展:看一下对快速排序的改进p244,使用随机数算法选取基准元素。

ADL代码

算法Partition(R, m, n. j)
/*负责从子数组[Rm, Rn]中选择一个基准元素,并把比它小的元素交换到数组的右边,比它大的元素交换到数组的左边。
 *返回值j是基准元素的下标。
 */
P1.[选取一个基准元素]
    base <- R[m].
P2.[交换]
    left <- m + 1. right <- n.
    WHILE left < right DO
    (
    	IF (R[left] > base && R[right] < base) THEN
    	(
    		R[left] <-> R[right].
            left <- left + 1.
            right <- right - 1.
        )	
    	ELSE IF R[left] <= base THEN
    		left <- left + 1.
    	ELSE
    		right <- right - 1.
	)
P3. [返回基准元素]
    IF R[left] > base
    (
    	R[left - 1] <-> R[m].
    	j <- left - 1.
	)
    ELSE
    (
    	R[left] <-> R[m].
    	j <- left.
	)|
    
算法QSort(R, m, n. R)
Q1. [递归出口]
IF (m == n || m > n) RETURN.
Q2. [划分数组]
    Partition(R, m, n. j).
Q3. [递归]
    QSort(R, m, j - 1. R).
    Qsort(R, j + 1, n. R).|

复杂度

3. 插入类排序

3.1 直接插入排序

原理:两层循环,第一层循环标记前k个已经排好序的元素的下一个元素i,第二层循环将i插入到前k个元素中,使前k+1个元素有序。

ADL代码

在这里插入图片描述

复杂度:复杂O(n2),最好情况下下O(n)。空间O(1)

3.2 希尔排序

原理:直接插入排序的性能与待排序数组本身的**”有序度“高度相关,原数组越有序,时间复杂度就越接近O(n),原数组越无序,时间复杂度越接近O(n2)。特别是远距离的逆序对比近距离的逆序对会显著增加比较次数**。

例如,下面这个数组(2, 1)这个逆序对需要比较101次才能调整有序

[..., 0, 2, ...100个元素..., 1, ...]

而,下面这个数组(2, 1)这个逆序对只需要比较11次。

[..., 0, 2, ...10个元素..., 1, ...]

那么为了尽量减少原数组中远距离的逆序对,需要直接在大的步长的子数组中进行排序,

例如,假设原数组有1000个元素,那么可以先选取步长为100,将如下子数组单独进行直接插入排序

// 这里 子数组中的数字是下标而非元素的值
[1, 101, 201, ..., 901],
[2, 102, 202, ..., 902],
[3, 103, 203, ..., 903],
...
[100, 200, 300, ..., 1000]

之后逐步减少步长,然后进行排序,直到最后步长为1:

[1, 2, 3, ...,  1000]	// 退化为原始的直接插入排序

这样,最后原数组会完全有序。

ADL代码

在这里插入图片描述

4. 其它排序

4.1 归并排序

原理:类似快速排序,归并排序也利用了分而治之的思想,但是它是自底向上分治。步骤如下:

  1. 如果待排序的数组为空或者大小为1,直接返回
  2. 将数组从中间分开,对两个子数组分别进行以上操作
  3. 这时两个子数组已经有序,对两个子数组进行归并,然后返回

ADL代码

算法Merge(R, t, m, n. X)
/**/
    建立X。
    
    
算法MSort(R, m, n. R)
/**/
M1.[递归出口]
	IF m == n OR m > n THEN
    	RETURN.
M2.[划分数组]
    mid <- (m + n) / 2.
    MSort(R, m, mid. R).
    Msort(R, mid + 1, n. R).
M3.[归并]
    Merge(R, m, mid, n. R).|
    

时间复杂度:O(nlogn)

4.2 基数排序/桶排序

不常考,了解即可。可能考简答题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据治理平台建设规划方案(71页WORD)

随着信息化时代的到来&#xff0c;大数据已成为企业管理和决策的重要基础。然而&#xff0c;大数据的快速增长和复杂性给数据的管理和治理带来了巨大挑战。为了有效应对这些挑战&#xff0c;构建一个高效、稳定的大数据治理平台显得尤为重要。 文档介绍&#xff1a; 该平台旨在…

零基础Java第十期:类和对象(一)

目录 一、拜访对象村 1.1. 什么是面向对象 1.2. 面向对象与面向过程 二、类定义和使用 2.1. 类的定义格式 2.2. 类的定义练习 三、类的实例化 3.1. 什么是实例化 3.2. 类和对象的说明 四、this引用 4.1. 什么是this引用 4.2. this引用的特性 一、拜访对象村 在…

基于SSM考研助手系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教学秘书管理&#xff0c;考研资讯管理&#xff0c;考研名师管理&#xff0c;考研信息管理&#xff0c;系统管理 教学秘书账号功能包括&#xff1a;系统首页&#xff0c;个人中心…

让你的 IDEA 使用更流畅 | IDEA内存修改

随着idea使用越来越频繁&#xff0c;笔者最近发现使用过程中有时候会出现卡顿现象&#xff0c;例如&#xff0c;启动软件变慢&#xff0c;打开项目的速度变慢等&#xff1a; 因此如果各位朋友觉得最近也遇到了同样的困惑&#xff0c;不妨跟着笔者一起来设置IDEA的内存大小吧~ …

基于Bert+Attention+LSTM智能校园知识图谱问答推荐系统

获取更多完整项目代码数据集&#xff0c;点此加入免费社区群 &#xff1a; 首页-置顶必看 1. 项目简介 本项目旨在实现基于ALBERT模型的命名实体识别&#xff08;NER&#xff09;任务。ALBERT&#xff08;A Lite BERT&#xff09;是谷歌提出的轻量级BERT模型&#xff0c;具有…

贪心算法与盛雨水问题

啥是盛雨水问题&#xff1f;给个图就熟悉了 欸&#xff1f; 这其中的关键在于&#xff1a; 1. 容量2D化就是长 * 宽 2. 木桶效应&#xff1a;宽取决于短板。 那我们来分析&#xff0c;怎么样能达到最佳的结果呢&#xff1f;穷举一下所有可能性不就好了&#xff1f;每两个板子…

ArcGIS001:ArcGIS10.2安装教程

摘要&#xff1a;本文详细介绍arcgis10.2的安装、破解、汉化过程。 一、软件下载 安装包链接&#xff1a;https://pan.baidu.com/s/1T3UJ7t_ELZ73TH2wGOcfpg?pwd08zk 提取码&#xff1a;08zk 二、安装NET Framework 3.5 双击打开控制面板&#xff0c;点击【卸载程序】&…

【c++篇】:解析c++类--优化编程的关键所在(二)

文章目录 一.默认成员函数二.构造函数2.1.构造函数的概念2.2构造函数的特性 三.析构函数3.1析构函数的概念3.2析构函数的特性 四.拷贝构造函数4.1拷贝构造函数的概念4.2拷贝构造函数的特性 五. 赋值运算符重载5.1运算符重载5.2赋值运算符重载5.3前置和后置重载 六.const成员七.…

【业务】群组服务功能重构测试总结

背景&#xff1a; 群组微服务重构想法上半年就开始了&#xff0c;目前老群组服务除了代码设计不合理&#xff0c;服务部署无法启动也是痛点。研发侧发起技术重构。 测试角度来说我这边痛点有三个&#xff1a; 业务不熟悉也没有完整有效case->有哪些功能点&#xff0c;那些…

docker 单节点arm架构服务器安装zookeeper、kafka并测试通信

kafka、zookeeper常用镜像介绍 kafka和zookeeper常见的镜像有以下三个&#xff1a;wurstmeister/zookeeper、kafka、confluentinc/cp-zookeeper、cp-kafka 和 bitnami/zookeeper、kafka。 wurstmeister/xxx: 由wurstmeister团队维护&#xff0c;提供的镜像适用于开发和测试环…

Mac apache配置cgi环境-修改httpd.conf文件、启动apache

Mac自带Apache&#xff0c;配置CGI&#xff0c;分以下几步&#xff1a; 找到httpd.conf。打开终端&#xff0c;编辑以下几处&#xff0c;去掉#或补充内容。在这个路径下写一个测试文件.py格式的&#xff0c;/Library/WebServer/CGI-Executables&#xff0c;注意第一行的python…

矩阵概念 和 性质

目录 一、矩阵因式分解 二、矩阵在图形学的运用 一、矩阵因式分解 1、先将矩阵化为上三角阵&#xff0c;得到U 2、每个主元列以下元素 主元 得到下三角阵 二、矩阵在图形学的运用 二维移动&#xff1a; 子空间H&#xff1a; 零向量属于H 对H中任意向量u、v&#xff0c;uv…

2024-10-25 算法学习及论文辅导(每日更新,随时联系)

看看学习小群的学习氛围&#x1f447;&#x1f3fb; 很多同学自己学习遇到问题没人解决&#xff0c;最终消耗了时间&#xff0c;精力同时大大消耗了自己对学习的信心&#x1f627; &#x1f973;来看看跟班学习&#xff0c;大家遇到问题的时候是怎么解决的&#xff1a; 首先…

idea安装visualVm插件

idea 安装visualVM插件用于分析java程序&#xff0c; 1.在插件市场安装visualvm launcher 2.安装成功后&#xff0c;重启idea&#xff0c;此时启动按钮旁边有这两个按钮 3.需要在这里配置插件的visualvm位置 4.配置完后&#xff0c;点击启动

ArcGIS计算落入面图层中的线的长度或面的面积

本文介绍在ArcMap软件中&#xff0c;计算落入某个指定矢量面图层中的另一个线图层的长度、面图层的面积等指标的方法。 如下图所示&#xff0c;现在有2个矢量要素集&#xff0c;其中一个为面要素&#xff0c;表示某些区域&#xff1b;另一个为线要素&#xff0c;表示道路路网。…

Linux相关概念和易错知识点(16)(Shell原理、进程属性和环境变量表的联系)

Shell原理及其模拟实现 在认识进程exec系列函数、命令行参数列表、环境变量之后&#xff0c;我们可以尝试理解一下Shell的原理&#xff0c;将各方知识串联起来&#xff0c;让Shell跑起来才能真正理解这些概念。我会以模拟Shell执行的原理模拟一个Shell。途中配上相关讲解。 1…

InnoDB 存储引擎<一>InnoDB简介与MySQL存储架构及相关数据结构

目录 回顾MySQL架构 InnoDB简介 ​MySQL存储结构 回顾MySQL架构 对MySQL架构图的总结: MySQL服务器是以网络服务的方式对外提供数据库服务的&#xff0c;我们使用的应用程序以及客户端统称为外部程序。 外部程序通过发送网络请求的方式来连接MySQL服务器&#xff0c;这时首先每…

Leetcode239. 滑动窗口最大值

问题描述&#xff1a; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a;nums [1,3,…

Python爬虫教程:从入门到精通

Python爬虫教程&#xff1a;从入门到精通 前言 在信息爆炸的时代&#xff0c;数据是最宝贵的资源之一。Python作为一种简洁而强大的编程语言&#xff0c;因其丰富的库和框架&#xff0c;成为了数据爬取的首选工具。本文将带您深入了解Python爬虫的基本概念、实用技巧以及应用…

文件下载漏洞

文件安全 文件下载 常见敏感信息路径 Windows C:\boot.ini //查看系统版本 C:\Windows\System32\inetsrv\MetaBase.xml //IIS配置文件 C:\Windows\repair\sam //存储系统初次安装的密码 C:\Program Files\mysql\my.ini //Mysql配置 C:\Program Files\mysql\data\mysql\user.…