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

news2024/9/25 18:35:26

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

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);//递归的右半部分   
	}
	else
        Insertion_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),归并排序稳定,但需额外空间,处理大数据时可能会受到限制。

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

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

相关文章

【病毒分析】新兴TOP2勒索软件!存在中国受害者的BianLian勒索软件解密原理剖析

1. 概述 近期&#xff0c;笔者在浏览网络中威胁情报信息的时候&#xff0c;发现美国halcyon.ai公司于2024年3月25日发布了一篇《Ransomware on the Move: LockBit, BianLian, Medusa, Hunters International》报告&#xff0c;此报告对当前勒索软件团伙的实力进行了排名&#…

裸土检测算法实际应用、裸土覆盖检测算法、裸土检测算法

裸土检测算法主要用于环境保护、农业管理、城市规划和土地管理等领域&#xff0c;通过图像识别技术来检测和识别地表上的裸露土壤。这种技术可以帮助管理者实时监控裸土面积&#xff0c;及时采取措施&#xff0c;防止水土流失、环境污染和生态退化。 一、技术实现 裸土检测算…

【第二轮通知】第二届网络、通信与智能计算国际会议(NCIC 2024)

NCIC 2024|第二届网络、通信与智能计算国际会议 2024年11月22日-25日 中国 | 北京 www.icncic.org 重要日期 二轮截稿时间&#xff1a;2024年10月15日 注册截止时间&#xff1a;2024年11月10日 会议日期&#xff1a;2024年11月22日-25日 第二届网络、通信与智能计算国际会…

ProgrammerAI—AI辅助编程学习指南

前言 随着AIGC&#xff08;AI生成内容&#xff09;技术的快速发展&#xff0c;诸如ChatGPT、MidJourney和Claude等大语言模型相继涌现&#xff0c;AI辅助编程工具正逐步改变程序员的工作方式。这些工具不仅可以加速代码编写、调试和优化过程&#xff0c;还能帮助解决复杂的编程…

【深度学习】注意力机制与自注意力机制详解

深度学习中的注意力机制/自注意力机制详解 1. 注意力机制的通俗理解2. 注意力和自注意力机制的区别3. 自注意力机制原理与计算流程3.1 引入自注意力机制的目的与思想3.2 从向量角度理解 [R1]3.3 从Self-Attention核心公式理解 [R3] 4. 多头自注意力机制&#xff08;Multi-head …

网络威慑战略带来的影响

文章目录 前言一、网络威慑的出现1、人工智能带来的机遇二、网络空间的威慑困境1、威慑概念的提出2、网络威慑的限度3、人类对网络威胁的认知变化4、网络空间的脆弱性总结前言 网络威慑是国家为应对网络空间风险和威胁而采取的战略。冷战时期核威慑路径难以有效复制至网络空间…

HT6881 4.7W防削顶单声道音频功率放大器

特点 防削顶失真功能(Anti-Clipping Function,ACF) AB类/D类切换 优异的全带宽EMI抑制性能 免滤波器数字调制&#xff0c;直接驱动扬声器 输出功率 1.4W (VDD3.6V, RL4Ω, THDN10%, Class D) 2.8W (VDD5.0V, RL4Ω, THDN10%, ClassD) 4.7W(VDD6.5V,RL40,THDN10%, ClassD) 2.5W …

【环境踩坑系列】centos7安装python3.10.X

前言 虽然centOS8已经发布了相当一段时间了&#xff0c;但是基于稳定性、成熟的社区等原因&#xff0c;大家在选择centOS作为服务器操作系统的时候仍然会选择centOS7作为首选。但是centOS7自带的是python2.7.5&#xff0c;当前大量的python程序要用到的又是python3&#xff0c…

网络原理之IP协议(网络层)

目录 前言 什么是IP协议&#xff1f; IP协议的协议头格式 16位总长度&#xff08;字节数&#xff09; 16位标识、3位标志位和13位片偏移 8位生存时间 IP地址管理 1.动态分配IP 2.NAT机制&#xff08;网络地址转换&#xff09; NAT机制是如何工作的 NAT机制的优缺点…

监控易监测对象及指标之:全面监控Oracle ODBC数据库

在数字化时代&#xff0c;数据库作为存储和管理企业核心数据的基石&#xff0c;其稳定性和性能直接关系到业务的连续性和效率。Oracle数据库以其强大的功能和稳定性&#xff0c;广泛应用于各行各业。为了确保Oracle数据库的稳定运行和高效性能&#xff0c;对其进行全面监控显得…

阴影的基本原理

1、现实中阴影的产生规则 如图所示&#xff0c;现实中的阴影产生规则是&#xff0c;在不考虑光线反射的前提下&#xff0c;当一个光源发射的一条光线遇到一个不透明物体A时&#xff0c;这条光线就不能够再继续照亮其他物体了&#xff08;物体B的一部分&#xff09;&#xff0c…

ChatGPT 向更多用户推出高级语音模式:支持 50 种语言;字节发布两款新视频生成大模型丨 RTE 开发者日报

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

AutosarMCAL开发——基于EB MCU驱动

这里写目录标题 1.MCU模块的作用2.EB配置以及接口应用3.总结 1.MCU模块的作用 MCU模块主要分为三部分&#xff1a; McuGeneralConfiguration MCU通用配置&#xff08;一般保持默认&#xff09;McuHardwareResourceAllocationConf 硬件资源分配管理器&#xff08;用于连接不同…

TEDxDUTH 使用 NocoBase 实现革新

作者&#xff1a;TEDxDUTH TEDxDUTH 是由德莫克里特大学的志愿者们组成的一个充满活力的团队。作为 TEDx 全球社区的一员&#xff0c;我们的使命简单而有力&#xff1a;传播能够激励和引发改变的思想。我们通过精心策划一系列活动&#xff0c;成功汇聚了众多思想家、创新家以及…

Module did not self-register: ‘drivelist.node‘报错解决

报错如下&#xff1a; node_modules/bindings/bindings.js:121throw e;^Error: Module did not self-register: xxxx/node_modules/drivelist/build/Release/drivelist.node.at process.func [as dlopen] (electron/js2c/asar.js:140:31)at Object.Module._extensions..node (…

探索 Python 中的 AI 魔法:markdownify 库的奥秘

文章目录 探索 Python 中的 AI 魔法&#xff1a;markdownify 库的奥秘背景&#xff1a;为何选择 markdownify&#xff1f;库简介&#xff1a;markdownify 是什么&#xff1f;安装指南&#xff1a;如何安装 markdownify&#xff1f;函数用法&#xff1a;markdownify 的五个简单函…

【Qwen2-VL】通义多模态新作速读

Qwen2-VL https://github.com/QwenLM/Qwen2-VL 结构&#xff1a; 整体&#xff1a;6.75 亿个参数的 Vision Transformer &#xff08;ViT&#xff09; &#xff08;Dosovitskiy et al.&#xff0c; 2021&#xff09; Qwen2 预处理阶段&#xff1a; 朴素动态分辨率支持&…

工程车辆目标检测、工程车检测算法、工程车辆类型检测算法

工程车检测算法主要用于智能交通系统、建筑工地管理、矿山开采、物流运输等领域&#xff0c;通过图像识别技术来检测和识别工程车&#xff0c;以提高安全管理、交通流量管理和资源调度的效率。以下是关于工程车检测算法的技术实现、应用场景及优势的详细介绍。 一、技术实现 工…

VRP-SAM

不建议复现

uni-app - - - - - 小程序获取宿主语言

const systemInfo uni.getSystemInfoSync(); console.log(systemInfo);uni.showModal({title: 宿主语言,content: systemInfo.hostLanguage })官网地址&#xff1a;【uni-app getSystemInfoSync】