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

数据结构不再难懂:带你轻松搞定排序算法

数据结构入门学习(全是干货)——排序算法(下)

1 快速排序

1.1 算法概述

快速排序采用分而治之的策略,与归并排序相似。其核心在于选择一个主元(pivot)作为分割点。

  1. 分而治之
    1. 主元(pivot)=>中枢枢纽的意思

伪码描述
快速排序的最佳情况是每次都能将数组均分。

void Quicksort( ElementType A[],int N )
{if( N < 2 ) return;pivot = 从A[]中选一个主元;//主元的选择决定了快速排序到底快不快将S = { A[] \ pivot }将除了主元以外的元素分成两个独立子集://怎么分A1 = {a属于S | a <= pivot }和A2 = {a属于S | a >= pivot };//一部分由小于等于pivot元素来组成的,另一部分由大于等于pivot元素组成A[] = Quicksort(A1,N1) U {pivot} U Quicksort(A2,N2);
}

什么是快速排序算法的最好情况?每次正好中分

1.2 选主元

  1. 随机选择主元:使用 rand() 函数会影响性能。
  2. 取头、中、尾的中位数作为主元:例如,对于8、12、3,选择8为主元。
ElementType Median3( ElementType A[],int Left,int Right )
{int Center = ( Left + Right ) / 2;if( A[ Left ] > A[ Center ] )//三步的比较跟交换(保证从左到右的大小顺序)。左边比中间大Swap( &A[ Left ],&A[ Center ] );if( A[ Left ] > A[ Right ] )//左边比右边大Swap( &A[ Left ],&A[ Right ] );if( A[ Center ] > A[ Right ] )//中间比右边大Swap( &A[ Center ],&A[ Right ] );//这样三步交换下来,左边一定是最小的那个Swap( &A[ Center ],&A[ Right-1 ] );//将pivot藏到右边(为了之后方便,先将Center放到现在需要考虑的子列的最右边),然后就只需要考虑A[Left + 1]....A[ Right - 2]return A[ Right - 1];//返回pivot
}

1.3 子集划分

  1. i和j并非C语言指针,而是指向存放位置。
  2. 主元被移至最右侧。
  3. 对比主元与i、j的值并进行交换,直至完成分区。

快速排序的优势

  • 每次选择的主元最终会被放在其正确位置。
  • 相比于插入排序,不必每次都移动其他元素。

注意事项

  1. 如果存在与主元相等的元素:
    • 停止交换会导致不必要的多次交换,复杂度为NlogN。
    • 继续移动指针可能导致主元位置不稳定,复杂度为N²。
    • 结论:选择停止交换更为有效。

小规模数据处理

  • 对于小于100的元素,可能插入排序更快。
  • 解决方案:当数据规模小于设定阈值时,停止递归,直接调用插入排序。

1.4 算法实现

void Quicksort( ElementType A[],int Left,int Right )
{if( Cutoff <= Right - Left ){Pivot = Median3( A,Left,Right );//pivot是主元的意思,在这里返回的不仅仅只是一个主元的值//这里的Left参数是最小值,Right参数是最大值。真正的主元被藏在了Right-1的地方i = Left; j = Right - 1;for(;;){while(A[ ++i ] < Pivot ){}while(A[ --j ] < Pivot ){}if( i < j)Swap( &A[i],&A[j] );//i < j则证明中间还有其他元素,这时候就可以调换//如果i > j则这个子集划分应该结束了else break;}Swap( &A[i],&A[Right-1]);//把藏在right-1这个位置的主元换到A[i]的位置上面去Quicksort(A,Left,i-1);//递归的左半部分Quicksort(A,i+1,Right);//递归的右半部分   }elseInsertion_Sort(A+Left,Right-Left+1);//Right-Left+1:待排序列的总个数;A+Left:开始的地方
}

快速排序的标准接口设计

void Quick_Sort(ElementType A[], int N) 
{ /* 这里写什么?如下*/Quicksort( A, 0, N-1 );
}

2 表排序

2.1 算法概述

表排序适用于待排元素为复杂结构(如书籍)。其特点是不移动原始数据,仅移动指向它们位置的指针。

间接排序

  • 仅移动指针,通过定义指针数组作为表。
  • 定义一个指针数组作为"表"(table)
  • 交换的只是table的整数(指针),得到

2.2 物理排序

N个元素可由独立环组成。环内元素依赖于其指针值,形成互不交集的独立结构。

环判断
每访问空位后,令 table[i] = i。当 table[i] == i 时,环结束。

复杂度分析

  1. 最好情况:初始即有序。
  2. 最坏情况:有N/2个环,每个环包含2个元素,移动需3N/2次。
  3. 时间复杂度:T = O(mN),m为每个元素的复制时间。

3 基数排序

基于比较的排序算法其最坏时间复杂度下界为O(NlogN)。基数排序是一种非比较排序。

3.1 桶排序

基数排序是桶排序的扩展,通过数组作为指针的桶来存储数据。

count是数组,这个数组的每一个元素都是一个指针,一开始被初始化为空链表的头指针,所以一开始有101个空链表(对应了101个空的桶 )

假设一个学生考88分:先找到88这个桶,然后把学生信息插到这个链表的表头里

伪码描述
void Bucket_Sort(ElementType A[],int N)
{count[]初始化;while(读入一个学生成绩grade)将该生插入count[grade]链表;for( i=0;i<M;i++){if( count[i] )//桶不为空输出整个count[i]链表;}
}
桶排序算法的时间复杂度T(M, N)是多少?	T(N,M) = O(M+N)当M非常小的时候(例如4w个学生只有101个不同成绩值,那这个时候其实就相当于一种线性的算法)

3.2 基数排序

如果M>>N的话怎么办?

处理值在0到999之间的整数时,每位数有十种可能。

输入序列:6482165122772901343125"次位优先"(Least Significant Digit)=>简称LSD算法//什么是次位优先?假设目前手里是216,这个时候6 个位数是最次位,2 百位数是主位(有一种算法是主位优先)//比较先从个位数开始

步骤

  1. 建立十个桶。

  2. 根据个位数分配到相应的桶。

  3. 根据十位数分配。

  4. 根据百位数分配。

复杂度
设元素个数为N,基数为B,LSD的趟数为P,最坏时间复杂度为:T=O(P(N+B))。

3.3 多关键字排序

基数排序适用于多关键字排序:

  1. 主位优先:为每种花色建立桶,内部排序后合并。
  2. 次位优先:为面值建桶,直接合并结果,后续再根据花色建立桶。

次位优先方法效率更高,时间复杂度更低。


4 排序算法的比较

前三个算法为简单排序,时间复杂度较差,但实现简单且不需额外空间。

  • 冒泡排序与插入排序:稳定,但性能较差。
  • 简单选择排序:不稳定,性能差。
  • 希尔排序:打破下界,复杂度最坏情况下为O(N²),但仍不稳定。
  • 堆排序与归并排序:理论时间复杂度均为O(NlogN),归并排序稳定,但需额外空间,处理大数据时可能会受到限制。

相关文章:

数据结构不再难懂:带你轻松搞定排序算法

数据结构入门学习&#xff08;全是干货&#xff09;——排序算法&#xff08;下&#xff09; 1 快速排序 1.1 算法概述 快速排序采用分而治之的策略&#xff0c;与归并排序相似。其核心在于选择一个主元&#xff08;pivot&#xff09;作为分割点。 分而治之 主元(pivot)>…...

YOLOv8 OBB win10+ visual 2022移植部署

前言 想做一个目标旋转角度检测的工程&#xff0c;但是网上多少python的&#xff0c;或者linux的。在win10 visual 2022移植部署&#xff0c;记录一下。 参考 这篇文章没有C win10 环境下的部署教程&#xff0c;我相对于是对此做了补充。 1、下载工程 https://github.com/sh…...

E+H超声波物位仪FMU42-ATB2A22A

EH超声波物位仪FMU42-ATB2A22A是一款由德国EH&#xff08;恩德斯豪斯&#xff09;公司生产的超声波物位计&#xff0c;具有高精度、非接触式测量等特点&#xff0c;广泛应用于液体、浆料和粗料的物位测量。以下是对该产品的详细介绍&#xff1a; 一、产品特点 高精度测量&…...

Linux风险应对策略:保障系统安全的有效措施

Linux作为一种开源操作系统&#xff0c;因其稳定性和安全性被广泛应用于服务器、嵌入式系统和个人电脑等多个领域。然而&#xff0c;随着网络攻击手段的不断演变&#xff0c;Linux系统也面临着各种安全风险。本文将探讨Linux系统的主要风险及其应对策略&#xff0c;帮助用户提升…...

芝法酱学习笔记(0.3)——SpringBoot下使用mybatis做增删改查和报表

零、前言 书接上回&#xff0c;我们搭建了windows下的开发环境&#xff0c;并给出了一个hello world级别的多模块SpringBoot项目。 毕竟java后端开发&#xff0c;离不开数据库的操作&#xff0c;为方便后面内容的讲解&#xff0c;这里再做一期铺垫&#xff0c;core模块下新增一…...

windows msys2 编译x264 32位动态库

一、打开mingw32 查看gcc版本 gcc --version 提示找不到gcc&#xff0c;可以安装gcc pacman -S gcc 二、进入x264-master目录 cd /d/x264-master 执行 ./configure --prefix/d/x264-master/Bin --disable-asm --enable-static --enable-shared --disable-thread其中--disa…...

【pytorch】relu的实现逻辑

笔者最近在尝试实现AlexNet的底层算子&#xff0c;基于pytorch的框架&#xff0c;本文主要记录一下pytorch中是如何实现relu算子的。 首先最外层是位于torch\nn\modules\activation.py&#xff0c;主要代码如下&#xff1a; __constants__ ["inplace"]inplace: bool…...

【Python篇】深入机器学习核心:XGBoost 从入门到实战

文章目录 XGBoost 完整学习指南&#xff1a;从零开始掌握梯度提升1. 前言2. 什么是XGBoost&#xff1f;2.1 梯度提升简介 3. 安装 XGBoost4. 数据准备4.1 加载数据4.2 数据集划分 5. XGBoost 基础操作5.1 转换为 DMatrix 格式5.2 设置参数5.3 模型训练5.4 预测 6. 模型评估7. 超…...

简单学习 原码反码补码 学会了你才是真正的程序员了

一、简单介绍原码反码补码 首先我们需要知道的是原码反码补码是一个人为的行为&#xff0c;因为机器看的都是所谓的补码&#xff0c;这个反码只是作为补码的到原码也就是人能看懂的跳板&#xff0c;所以计算机无论是计算器里面的东西还是他底层运行的二进制代码都是补码&#x…...

基于规则的命名实体识别

基于规则的命名实体识别&#xff08;Rule-Based Named Entity Recognition, NER&#xff09;是一种通过预定义的模式或规则来识别文本中特定实体的方法。这种方法通常使用正则表达式来匹配文本中的实体。下面是一个更完整的示例&#xff0c;展示了如何使用正则表达式来识别文本…...

C语言从头学63—学习头文件stdlib.h(二)

6、随机数函数rand() 功能&#xff1a;产生0~RAND_MAX 之间的随机整数。 使用格式&#xff1a;rand(); //无参 返回值&#xff1a;返回随机整数 说明&#xff1a; a.RAND_MAX是一个定义在stdlib.h里面的宏&#xff0c;表示可以产生的最大随机整数&am…...

js判断一个对象里有没有某个属性

1. 使用in操作符 in操作符可以用来检测属性是否存在于对象或其原型链中。 const obj {a: 1, b: 2}; if (a in obj) { console.log(属性a存在于obj中); } else { console.log(属性a不存在于obj中); } 2. 使用hasOwnProperty()方法 hasOwnProperty()方法用来检测一个…...

Python(爬虫)正则表达式

正则表达式是文本匹配模式&#xff0c;也就是按照固定模式匹配文本 一、导入 re模块是Python环境的内置模块&#xff0c;所以无需手动安装。直接在文件中导入即可&#xff1a; import re 二、正则表达式基础知识 . 匹配除换行符以外的任意字符 ^ 匹配字符串的开始 $ 匹配字…...

Linux:进程(二)

目录 一、cwd的理解 二、fork的理解 1.代码共享 2.各司其职 3.fork的返回值 三、进程状态 1.进程排队 2.进程状态 运行状态 阻塞状态 挂起状态 一、cwd的理解 cwd&#xff08;current working directory&#xff09;。译为当前工作目录。 在C语言中&#xff0c;使用…...

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第二篇-着色器制作】

在上一篇文章中&#xff0c;我们已经理顺了实现流程。 接下来&#xff0c;我们将在UE5中&#xff0c;从头开始一步一步地构建一次流程。 通过这种方法&#xff0c;我们可以借助一个熟悉的开发环境&#xff0c;使那些对着色器不太熟悉的朋友们更好地理解着色器的工作原理。 这篇…...

【OceanBase 诊断调优】—— GC问题根因分析

GC 流程涉及到 RS 的状态切换和 LS 的资源安全回收&#xff0c;流程上较长。且 GC 线程每个租户仅有一个&#xff0c;某个日志流 GC Hang 死时会卡住所有其余日志流的 GC&#xff0c;进而造成更大的影响。 本文档会帮助大家快速定位到 GC 故障的模块&#xff0c;直达问题核心。…...

图像面积计算一般方法及MATLAB实现

一、引言 在数字图像处理中&#xff0c;经常需要获取感兴趣区域的面积属性&#xff0c;下面给出图像处理的一般步骤。 1.读入的彩色图像 2.将彩色图像转化为灰度图像 3.灰度图像转化为二值图像 4.区域标记 5.对每个区域的面积进行计算和显示 二、程序代码 %面积计算 cle…...

指挥平台在应急场所中的主要表现有哪些

在应对自然灾害、公共安全事件等突发危机时&#xff0c;指挥平台作为应急管理体系的核心枢纽&#xff0c;其重要性不言而喻。它不仅承载着信息的快速汇聚、精准分析与高效调度功能&#xff0c;更在应急场所中有一定的关键表现。接下来就跟着北京嘉德立一起了解一下。 一、信息集…...

智能养殖场人机交互检测系统源码分享

智能养殖场人机交互检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Co…...

数据集-目标检测系列-海洋鱼类检测数据集 fish>> DataBall

数据集-目标检测系列-海洋鱼类检测数据集 fish>> DataBall 数据集-目标检测系列-海洋鱼类检测数据集 fish 数据量&#xff1a;1W 数据项目地址&#xff1a; gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview github: https://github.com/…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...