部分类型排序(梳排序,归并排序,快速排序,基数排序)的简单梳理

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

常见的排序可分为比较排序及其非比较排序,其中比较排序较常用的有冒泡排序,归并排序,插入排序,选择排序,快速排序,梳排序等等;非比较排序有桶排序,基数排序等等。我们将介绍其中的梳排序,归并排序,快速排序,基数排序。网上关于这些实现排序的方法可能有多种,这里每一种排序仅提供其中一种实现方法作为参考。

第一种:比较排序

梳排序:冒泡排序的优化版。

原理:交换的范围由冒泡的与旁边的数比较并,变成了与隔一段距离的数比较并交换,并每过一个循环减少这个距离,当距离为1时,就相当于冒泡,但是在退化成冒泡前,我们已经对数据进行了多次比较排序,所以进行冒泡的步骤就十分少了,变形加速了冒泡。所以速度>=冒泡

#include<stdio.h>
#define N 1000
int main()
{
int n;//要处理数据的大小
int i;//计数器
int j;//距离
int a[N];//存储数据的数组
    double k=1.3;//距离递减值,可以是其他,但1.3测试的效果较好
    scanf("%d",&n);
    for(i=0;i<n;i++){scanf("%d",&a[i]);}
    j=n-1;
    i=0;
    int flag=1;//判断是否有交换,如有交换循环还要继续,否则(部分)排序结束
    //两个条件同时满足时,才能认为数据中每一个数都被比较过并处理过
while(j>1||flag==1){
    j=(j/k>1)?(j/k):1;//每循环一次让 距离/递减值,减少距离,直到为1,则退化成冒泡
    flag=0;
i=0;
//下面进行冒泡
    while(i+j<n){
if(a[i]<a[i+j]){
        int temp=a[i];
        a[i]=a[i+j];
        a[i+j]=temp;
        flag=1;
    }//大到小排序,交换
     i++;
    }
    }
    for(i=0;i<n;i++){printf("%d ",a[i]);}//输出
    return 0;
}

归并排序:稳定的高速算法

原理:借助分治法,将要处理的数据分半,再分半,直到只剩两个数的时候不能再分,开始对分半到最后的那一堆数据(子数据)分别进行排序
步骤:

1. 每个子数据中的数比较大小并换位
2. 递归到上一步,和旁边的(排好序的)子数据进行合并
(合并步骤:)

  1. 临时建立一个空数组Z[ n ]
  2. 比较两个子数据a[ i ],b[ j ]首元素大小,大的(如果是a[0])则放进Z[0]
  3. 然后比较a[1]和b[0],大的放进Z[1](每放进一次,Z和放进元素的数组下标+1)
  4. 重复
  5. 如果两个子数据长度不等,把剩下的元素不按顺序直接放进Z
  6. 回到2,直到全部合并。

因为该方法无论数据大小只会影响分半速度,所以该方法比较稳定,无论如何速度>冒泡。
但不一定大于梳排序。

代码描述可能更容易理解:

#include<stdio.h>
#define N 1000
void Mergesort(int a[],int L,int R);
int main()
{
    int n,i;
    int a[N];
    scanf("%d",&n);
    for(i=0;i<n;i++){scanf("%d",&a[i]);}
    Mergesort(a,0,n);
    for(i=0;i<n;i++){printf("%d ",a[i]);}
    return 0;
}

void Mergesort(int a[],int L,int R)
{
if(L>R-2){return;}//当数据只剩下1个的时候,结束,回到上一层递归
int middle=(L+R)/2;//中间值,负责分半

Mergesort(a,L,middle);
Mergesort(a,middle,R);//把数据分开两半

int x=L;//子数据1的下标
int y=middle;//子数据1旁边的子数据2的下标
int t=L;//空白数组的下标
int turn[N]={0};//空白数组

while(x<middle||y<R)//对a[L]……a[middle-1],和对a[middle]…….a[R-1]数据进行合并
{
    if(y>=R||(x<middle&&(a[x]>=a[y]))){turn[t++]=a[x++];}//把大的先放进去turn[ ],达到从大到小排序的目的。忘了x<middle时循环可能会越过middle边界。如果子数据2已经越了界,则把子数据1全部放入turn[ ]中
    else{turn[t++]=a[y++];}
}

for(int i=L;i<R;i++){
a[i]=turn[i];
}//把turn[ ]中排好的数据放回原来的数组

}

这种递归算法虽然会有空间上的开销(空白数组的开设),和时间上的开销(递归,调用函数)。但是比较好理解,容易易写和相对不容易出错,有兴趣可以上网查一下非递归版本

快速排序:不稳定的更高速算法

原理:也同样用到分治法,将将数据分成两部分再分。不同的是对于每一组数据,将选取其中一个数作为基准,然后分别将大于基准数的元素置于基准数左边,小于则放于右边,最后将基准数两边的数据分开,分别继续刚才的步骤,直到不能再分,但此时,全部数据已经完成排序。

不稳定性:假如我们要将一组数据按大到小排序,而这组数据原来是由小到大排序的话,这时快速排序效率等于冒泡排序,甚至还慢了一点(函数调用),但大部分情况下,快速排序效率高于其他排序,广泛运用于各种函数库。

#include<stdio.h>
#define N 1000
void quicksort(int a[],int L,int R);
void Swap(int *a,int*b);
int main()
{
    int n,i;
    int a[N];
    scanf("%d",&n);
    for(i=0;i<n;i++){scanf("%d",&a[i]);}
    
    quicksort(a,0,n);
    
    for(i=0;i<n;i++){printf("%d ",a[i]);}
    return 0;
}
void quicksort(int a[],int L,int R){
if(L==R-1){return;}
int x=L+1,y=R-1;
while(x!=y){
    while(a[y]<a[L]&&y>x){y--;}
    while(a[x]>a[L]&&x<y){x++;}
    if(x<y){Swap(&a[x],&a[y]);}
}

if(a[L]<a[y])Swap(&a[L],&a[y]);

quicksort(a,L,x);
quicksort(a,x,R);
}

void Swap(int *a,int*b){
int temp=*a;
*a=*b;
*b=temp;
return;
}

第二种:非比较排序

基数排序:处理小数据的有效排序

输入数据,边输入边边比较各个元素的位数,取出最大位数
进入排序的函数中,从1位(个位数)开始,将元素按照个位数(此时个位数为排序基数)大小的顺序临时放在一个空白数组中,大的放前面,小的放后面。放完后,对2位(十位,此时十位数为排序基数)开始,重复刚才的步骤,如果小于2位,则优先放在最前面。
重复刚才步骤,直到位数过了最大的位数。排序结束了。

该方法通常用于处理小的自然数数据,稳定,比冒泡快。

#include<stdio.h>
#define N 1000
int main()
{
    int n,i;
    int a[N];
    scanf("%d",&n);
    int all=-1;
    
    for(i=0;i<n;i++)
    {
    int s=0;
    scanf("%d",&a[i]);
    int x=a[i];
    while(x){s++;x/=10;}
    if(s>all){all=s;}//找到最大位数
    }
    
    int lo=1;//排序从1(个位)开始
    while(lo<=all){
    int k=1;
    int Lo=lo;
    
    while(--Lo){
        k=k*10;//用来处理元素的工具
    }
    
    int A[n+3]={0};
    int j,c=0;
    
    for(i=9;i>=0;i--){
        for(j=0;j<n;j++){
            if((a[j]/k)%10==i)//对每一个元素,先/k使其最后一位变成我们现在进行排序的位数,如我们现在要排2(十位),使123/10=12,12%10=2,2即为123的十位数。
        {
                A[c++]=a[j];//基数大元素的先放进空白数组。
        }
        }
    }
 
    for(i=0;i<n;i++){a[i]=A[i];}//空白数组中的数据回到原数组
    lo++;
    }
    
    
    for(i=0;i<n;i++){printf("%d ",a[i]);}
    
    return 0;
}

所学排序的简单梳理就到这里,欢迎大家提出建议。

基于大模型的恶性胸腔积液全周期预测与诊疗方案研究 本研究基于大模型技术构建了恶性胸腔积液全流程预测与诊疗体系,涵盖术前风险评估、术中方案优化、术后恢复预测及并发症预防。通过整合多源医疗数据,实现了手术风险概率预测(准确率80%)、并发症预警(AUC值0.85)及个性化康复方案制定,显著提升诊疗精准度。研究创新性地将Transformer架构与多模态数据融合,在100例临床验证中显示良好性能,但存在数据样本局限、模型可解释性不足等问题。未来将扩大多中心临床验证,优化算法可解释性,探索与基因检测等技术的结合应用,推动恶性胸腔积液的精准诊疗发展。 阅读详情

相关推荐

AI开发提效10倍:从需求到部署的全流程实战指南(附Prompt模板)

用AI开发不是“偷懒”,而是把时间花在更有价值的地方——原来花80%时间写重复代码,现在用AI搞定后,能把精力放在“优化用户体验”“提升系统性能”这些核心工作上,这才是AI给开发者的真正红利。如果你还没开始用AI做开发,建议从“写一个简单接口”“补一段注释”开始尝试,先用起来再优化方法。记住:AI是工具,不是对手,学会驾驭它,你会发现开发效率提升的同时,还能告别无效加班。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1530

常见的七种排序

插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序

Fighting!!! 1047

关于【中孚计算机终端保密检查系统】的卸载

卸载中孚计算机终端保密检查系统

码农之路,向死而生 4万+

梳排序算法讲解

嗯,历史山这些算法的名字总是,嗯,不知道如何说,反正充满了想象力,不过也恰恰形象的说明了这个算法 梳排序,跟梳子一样,齿和齿中间有间隙,这个间隙是多少呢,是1.3,嗯,记住就好,为啥是1.3,数学功底比较强的人可以去看看哈,我们这就不做太多讨论,直接举例 有数组[6, 4, 5, 1, 8, 7, 2, 3] 我们先来算算间隙,上面的数组长度为8,8/1.3=6,则间隙为6 我们开始遍历数...

美丽的泡沫 897

2024高校网络安全管理运维赛题目--复现+题目+wp

官方writeup集思广益比较好的备份。

书山有路勤为径,学海无涯苦作舟 1323

自定义View系列教程04--Draw源码分析及其实践

通过之前的详细分析,我们知道:在measure中测量了View的大小,在layout阶段确定了View的位置。 完成这两步之后就进入到了我们相对熟悉的draw阶段,在该阶段真正地开始对视图进行绘制。按照之前的惯例,我们来瞅瞅View中draw( )的源码 public void draw(Canvas canvas) { final int privateFlags = mPriv

谷哥的小弟 2万+

梳排序(Comb sort)

梳排序(Comb sort)是一种由Wlodzimierz Dobosiewicz于1980年所发明的不稳定排序算法,并由Stephen Lacey和Richard Box于1991年四月号的Byte杂志中推广。梳排序是改良自泡沫排序和快速排序,其要旨在于消除乌龟,亦即在阵列尾部的小数值,这些数值是造成泡沫排序缓慢的主因。相对地,兔子,亦即在阵列前端的大数值,不影响泡沫排序的效能。 在泡沫排序中,只比较阵列中相邻的二项,即比较的二项的间距(Gap)是1,梳排序提出此间距其实可大于1,改自插入排序的希尔排序同

heyuchang666的专栏 1957

【AI测试必学】DeepSeek API 快速入门:获取 API Key 与调用 API 步骤详解

DeepSeek API 使用与 OpenAI 兼容的格式,可以通过修改配置使用 OpenAI SDK。生成的 API Key 只会显示一次,请妥善保存。注册并登录账号,进入左侧导航栏的。创建 API Key。

blues_C的博客 1万+

十种常见的排序算法

1.常见算法分类 十种常见排序算法一般分为以下几种: (1)非线性时间比较类排序:交换类排序(快速排序和冒泡排序)、插入类排序(简单插入排序和希尔排序)、选择类排序(简单选择排序和堆排序)、归并排序(二路归并排序和多路归并排序); (2)线性时间非比较类排序:计数排序、基数排序和桶排序。 总结: (1)在比较类排序中,归并排序号称最快,其次是快速排序和...

weixin_30920091的博客 4361

24、企业治理、风险与合规:精益思维的应用与实践

本文探讨了如何运用精益思维优化企业治理、风险与合规(GRC)流程,分析了职责分离与合规流程的误区,提出了预防性与检测性控制措施的合理搭配,并通过价值流映射、减少合规反馈循环等方法实现流程优化。以Etsy的PCI-DSS实施为例,展示了如何在满足法规要求的同时保持创新活力。文章还强调了构建协作型GRC文化的重要性,并展望了未来GRC的发展趋势,包括数字化转型、全球化风险管理及与可持续发展的结合。

solidity8miner的博客 103

【HAL库】STM32CubeMX开发----STM32F407----ETH+LAN8720A+LWIP----ping通

本次实验以芯片为MCU,使用25MHz外部时钟源。以太网PHY层芯片为LAN8720A,由MCU引脚PA8提供时钟。

MQ0522的博客 4843

排序方法(数据结构)

经典排序算法 经典排序算法,以下文章参考了大量网上的资料,大部分都给出了出处这一系列重点在理解,所以例子什么的都是最简单的情况,难免失误之处,多指教大多数排序算法都给出了每一步的状态,以方便初学者更容易理解,通俗易懂,部分难以理解的排序算法则给出了大量的图示,也算是一个特色吧经典排序算法 - 快速排序Quick sort经典排序算法 - 桶排序Bucket sort经典排序算法 - 插入

Vilin的博客 264

前拉后推计划逻辑适用于哪些行业和企业规模?

《前拉后推计划逻辑的行业适用性分析》摘要:前拉后推计划逻辑(需求端后推锚定交付、供应端前拉匹配资源)最适用于需求波动大且具规模效益的行业,包括家具制造(定制化需求+批量运输)、机械装备(非标设备+部件采购)、消费电子(短周期产品+核心部件备货)及汽车配套(交期绑定+批量生产)等领域。该模式要求企业具备:1)独立计划部门;2)ERP/MES等信息系统;3)资源冗余能力,故更适配中型(1-10亿营收)和大型企业(10亿+)。小型企业需简化应用,仅聚焦关键环节。不适配需求稳定(如快消品)、无规模效益或短周期生产的

追随内心 144

冒泡排序:从经典到大数据,一文掌握多种解法与演进

记录每一轮最后一次发生交换的位置,该位置之后的元素已经有序,下一轮只需遍历到此位置即可。return arr。

knowcai126的博客 223

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

MATLAB数学建模核心函数全解析:从数据预处理到模型求解实战指南

数学建模是将实际问题抽象为数学模型并求解的关键技术,广泛应用于工程、金融和科研领域。其核心原理在于通过数学语言描述系统行为,并利用计算工具寻找最优解或进行预测分析,技术价值在于将复杂现实问题转化为可量化、可复现的解决方案。在应用场景上,数学建模覆盖预测分析、优化决策和评估分类等典型任务。针对这些需求,MATLAB提供了强大的内置函数库,例如在数据预处理阶段,`readtable`和`fillmissing`能高效处理原始数据;在模型求解环节,`fmincon`和`ode45`分别擅长处理优化问题和微分方程。

weixin_30633405的博客 513

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

第零篇-算法全景图

本文不深入讲解具体实现,而是带你俯瞰整张算法知识地图——14 大领域、300+ 算法一次看全,帮你建立体系化认知,找到自己的学习路径。

晚风的博客 954

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 197

【算法拾光】链表 哈希表|K个一组翻转链表 + 两数之和

K个一组翻转链表需分段反转,借助哑节点与前驱指针维护连接,避免断链;两数之和利用哈希表实现O(1)查找,空间换时间,高效定位目标组合。前者考察链表指针操作,后者聚焦映射关系构建,均为面试高频题。

wuqingyigexiaoba的博客 307

排序算法深度笔记(下):非比较类排序的线性突破与工程边界

排序算法时间复杂度额外空间复杂度稳定性是否基于比较选择排序O(N^2)(O(1))不稳定是冒泡排序O(N^2)(O(1))稳定是插入排序O(N^2)(O(1))稳定是归并排序O(N\log N)(O(N))稳定是快速排序O(N\log N)O(log N)不稳定是堆排序O(N\log N)O(1)不稳定是计数排序(O(N + M))O(M))稳定否基数排序O(N)稳定否桶排序平均O(N) / 最坏O(N^2)

2401_87069538的博客 567

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 20

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 748

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 367

牛客周赛165C题(前后缀性质,递推,排序,枚举)

题目大意:给定长度为 `n` 的数组,选择 `k ∈ [1,n]`,将前 `k` 个元素整体翻转,后面的元素不变。要求操作后的整个数组非递减,统计满足条件的 `k` 的数量。题目链接:https://ac.nowcoder.com/acm/contest/141721/C。时间复杂度:O(nlogn)

2501_94316951的博客 170

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 82

算法61,判定是否为字符重排

两字符串能互为重排 ⇔。

sheshibenniaodan的博客 207

算法日常・每日刷题--<动态规划>32

给定严格递增的正整数数组,求最长斐波那契子序列长度。使用二维DP,dp[i][j]表示以arr[i]、arr[j]为最后两项的序列长度,初始化均为2。通过哈希表快速查找前一项target = arr[j] - arr[i],若存在且下标小于i,则状态转移:dp[i][j] = dp[k][i] + 1。遍历更新全局最大长度,最终若结果小于3则返回0。时间复杂度O(n²),空间复杂度O(n²)。

2503_92261635的博客 177
上一篇: BFS——广度优先搜索的简单易懂入门心得
下一篇: DFS——深度优先搜索的简单易懂入门心得
infinityfor
博客等级 码龄7年 1粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值