排序算法性能分析

news2024/9/20 15:03:54

目录

实现插入排序、冒泡排序、选择排序、合并排序、快速排序算法(从小到大)

①插入排序

②冒泡排序

③选择排序

⑥快速排序

五种排序

现在有10亿的数据(每个数据四个字节),请快速挑选出最大的十个数,并在小规模数据上验证算法的正确性。

方法一:规模为10的插入排序

方法二:规模为10的堆排序


实现插入排序、冒泡排序、选择排序、合并排序、快速排序算法(从小到大)

首先介绍各个排序算法的设计思路以及给出各个算法的伪代码,再通过伪代码具体实现每个排序算法。

①插入排序

设计思路:

假设前N-1个数已经是有序序列了,那么将第N个数插入其中仍使其有序的方法是依次和前N-1个数进行比较,找到合适的位置安放即可。

开始时,将第一个数作为有序序列,先从第2个数开始插入,重复操作,直到排序完成。

将1,2,3,4,4,9作为插入排序的例子,如图1所示。

图1 插入排序图示

伪代码:

matlab代码

result=[];
for power=1:5
    scale=power*10000;
    count=0;
    for times=1:20
        number=randi(scale,1,scale);
        tic;
        for i=1:scale-1
            for j=i+1:-1:2
                if number(j)>number(j-1)
                    break
                else
                    temp=number(j);
                    number(j)=number(j-1);
                    number(j-1)=temp;
                end
            end
        end
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end

算法复杂度分析:

最坏时间复杂度:O(n^2)

最好时间复杂度:O(n)

平均时间复杂度:O(n^2)

实际效率:

随机生成数据规模分别为10000,20000,30000,40000,50000的测试数据,每个数据规模记录20组的平均排序时间,数据记录如表1所示。

表1 插入排序

其中取第一个实验值作为理论值基准计算出理论值,如图2所示。

图2 插入排序

解释与分析:

由图2可知,在不同的数据规模下,插入排序的实验数据和理论计算基本一致。

②冒泡排序

设计思路:

比较相邻两个元素的大小,如果大小顺序不对则交换位置,这样一趟下来,最大的或者最小的就可以被分离出来,如此重复下去,直到排序完成。

将8,16,21,25,27,49作为冒泡排序的例子,如图3所示。

图3 冒泡排序图示

伪代码:

matlab代码

result=[];
for power=1:5
    scale=power*100;
    count=0;
    for times=1:20
        number=randi(scale,1,scale);
        tic;
        for i=scale:-1:1
            for j=1:i-1
                if number(j)>number(j+1)
                    temp=number(j);
                    number(j)=number(j+1);
                    number(j+1)=temp;
                end
            end
        end
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end

算法复杂度分析:

最坏时间复杂度:O(n^2)

最好时间复杂度:O(n^2)

平均时间复杂度:O(n^2)

实际效率:

随机生成数据规模分别为10000,20000,30000,40000,50000的测试数据,每个数据规模记录20组的平均排序时间,数据记录如表2所示。

表2 冒泡排序

其中取第一个实验值作为理论值基准计算出理论值,如图4所示。

图4 冒泡排序

解释与分析:

由图4可知,冒泡排序的实验数据比理论计算要大,并且随着数据规模的增大,这个差距也在增大,初步分析是数据规模小,所取的理论值基准较小,加上运行环境影响所致。

③选择排序

设计思路:

每次在序列中找出最小的元素,将它与第一个元素交换位置,接着找剩下序列中最小的元素,将它与第二个元素交换位置,如此重复,直到排序完成。

将8,16,21,25,27,49作为选择排序的例子,如图5所示。

图5 选择排序图示

伪代码:

matlab代码

result=[];
for power=1:5
    scale=power*10000;
    count=0;
    for times=1:20
        number=randi(scale,1,scale);
        tic;
        for i=1:scale-1
            for j=i+1:scale
                if number(i)>number(j)
                    temp=number(j);
                    number(j)=number(i);
                    number(i)=temp;
                end
            end
        end
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end

算法复杂度分析:

最坏时间复杂度:O(n^2)

最好时间复杂度:O(n^2)

平均时间复杂度:O(n^2)

实际效率:

随机生成数据规模分别为10000,20000,30000,40000,50000的测试数据,每个数据规模记录20组的平均排序时间,数据记录如表3所示。

表3 选择排序

其中取第一个实验值作为理论值基准计算出理论值,如图6所示。

图6 选择排序

解释与分析:

由图6可知,在不同的数据规模下,选择排序的实验数据和理论计算基本一致。

(4)归并排序

设计思路:

把序列分成很多的子序列,先每两个元素合并成一个有序序列,再每四个元素合并成一个有序序列,如此下去,直到整个序列有序。

将8,16,21,25,25*,49作为归并排序的例子,如图7所示。

图7 归并排序图示

伪代码:

matlab代码

result=[];
for power=1:5
    scale=power*100000;
    count=0;
    for times=1:20
        number=randi(scale,1,scale);
        done=zeros(1,scale);
        tic;
        step=1;
%         number=MergeSort(1,scale,number,done);
        while step<scale
            for low=1:2*step:scale
                mid=low+step-1;
                if mid>scale
                    break
                end
                high=low+2*step-1;
                if high>scale
                    high=scale;
                end
                done=Merge(low,mid,high,number,done);
            end
            step=step*2;
            number=done;
        end
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end
% function[number]=MergeSort(low,high,number,done)
%     if low<high
%         mid=floor((low+high)/2);
%         number=MergeSort(low,mid,number,done);
%         number=MergeSort(mid+1,high,number,done);
%         number=Merge(low,mid,high,number,number);
%     end
% end
function[done]=Merge(low,mid,high,number,done)
    i=low;
    j=mid+1;
    k=low;
    while i<=mid&&j<=high
        if number(i)<=number(j)
            done(k)=number(i);
            i=i+1;
        else
            done(k)=number(j);
            j=j+1;
        end
        k=k+1;
    end
    while i<=mid
        done(k)=number(i);
        k=k+1;
        i=i+1;
    end
    while j<=high
        done(k)=number(j);
        k=k+1;
        j=j+1;
    end
end

算法复杂度分析:

最坏时间复杂度:O(nlogn)

最好时间复杂度:O(nlogn)

平均时间复杂度:O(nlogn)

实际效率:

随机生成数据规模分别为10000,20000,30000,40000,50000的测试数据,每个数据规模记录20组的平均排序时间,数据记录如表4所示。

表4 归并排序

其中取第一个实验值作为理论值基准计算出理论值,如图8所示。

图8 归并排序

解释与分析:

由图8可知,归并排序的实验数据比理论计算要大,并且随着数据规模的增大,这个差距也在增大,初步分析是数据规模较小,所取的理论值基准较小,加上运行环境影响所致。

⑥快速排序

设计思路:

先取一个中轴元素,比如第一个元素,然后根据这个中轴元素将序列分成两个子序列,一个子序列里面的元素都比中轴元素小,另一个子序列里面的元素都比中轴元素大,然后再对子序列进行这样的操作,如此重复,直到排序完成。

将8,16,21,25,25*,49作为快速排序的例子,如图9所示。

图9

伪代码:

matlab代码

result=[];
for power=1:5
    scale=power*10000;
    count=0;
    for times=1:20
        number=randi(scale,1,scale);
        tic;
        number=Quick(1,scale,number);
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end
function[number]=Quick(low,high,number)
    i=low;
    j=high;
    pivot=number(low);
    while low<high
        while low<high&&pivot<=number(high)
            high=high-1;
        end
        if low<high
            number(low)=number(high);
            low=low+1;
        end
        while low<high&&pivot>number(low)
            low=low+1;
        end
        if low<high
            number(high)=number(low);
            high=high-1;
        end
    end
    number(low)=pivot;
    if i<low-1
        number=Quick(i,low-1,number);
    end
    if high+1<j
        number=Quick(high+1,j,number);
    end
end

算法复杂度分析:

最坏时间复杂度:O(n^2)

最好时间复杂度:O(nlogn)

平均时间复杂度:O(nlogn)

实际效率:

随机生成数据规模分别为10000,20000,30000,40000,50000的测试数据,每个数据规模记录20组的平均排序时间,数据记录如表5所示。

表5 快速排序

其中取第一个实验值作为理论值基准计算出理论值,如图10所示。

图10 快速排序

解释与分析:

由图10可知,快速排序的实验数据比理论计算要小,初步分析是数据规模小,所取的理论值基准较小,加上运行环境影响所致。

五种排序

以上五种排序实际运行效率如图11所示。

图11 五种排序比较

由图可以看出五种排序实际效率最快的是平均时间复杂度为O(nlogn)的快速排序和归并排序,然后是最优时间复杂度为O(n)的插入排序,最后是时间复杂度均为O(n^2)的冒泡排序和选择排序。

现在有10亿的数据(每个数据四个字节),请快速挑选出最大的十个数,并在小规模数据上验证算法的正确性。

算法设计思路:

对于10亿个数据从中挑选出最大的十个数,对10亿个数全部进行排序的方法显然不可取,可以通过选择排序或者冒泡排序进行10趟排序,但是这样需要进行的操作次数大概是100亿次,这里我们采取别的方法。

方法一:规模为10的插入排序

我们首先对前10个数进行降序排序,这样末尾的数是前10个数中最小的数,此后遍历剩下的10亿-10个数,对每一个数都和前10个数进行一趟插入排序,最少比较次数为1次,最多比较次数为10次,这样需要进行的操作次数大概是55亿次,比冒泡排序和选择排序减少了近一半的操作次数。

matlab代码

result=[];
for power=1:1
    scale=power*1000000000;
    count=0;
    for times=1:20
        numbers=randi(scale,1,scale);
        number=numbers(1,1:10);
        tic;
        for i=1:9
            for j=i+1:-1:2
                if number(j)<number(j-1)
                    break
                else
                    temp=number(j);
                    number(j)=number(j-1);
                    number(j-1)=temp;
                end
            end
        end
        for i=11:scale
            for j=10:-1:1
                if number(j)>=numbers(i)
                    break
                else
                    if j<10
                        number(j+1)=number(j);
                    end
                    number(j)=numbers(i);
                end
            end
        end      
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end

实际表现:

取数据规模为100W,200W,300W,400W,500W作为测试数据,每个数据规模测试20组,记录平均运行时间,如图12所示。

图12 规模为10的插入排序

测试一些大数据的运行时间(20组平均时间)如下:

一千万:0.0390s

五千万:0.1832s

一亿:0.3727s

五亿:1.8612s

十亿:5.6923s

方法二:规模为10的堆排序

方法一的规模为10的插入排序效率已经比较高了,但是仍有不足,即将10个最大的数也进行了排序,而实际上只需要将它们挑选出来即可,考虑建立规模为10的堆排序,这样最小比较次数为1次,但最大比较次数降到了3次,挑出10个最大的数理论上大概需要进行20亿次的操作即可。

matlab代码 

result=[];
for power=1:1
    scale=power*1000000000;
    count=0;
    for times=1:20
        numbers=randi(scale,1,scale);
        number=numbers(1,1:10);
        tic;
        for i=5:-1:1
            number=Adjust(i,10,number);
        end
        for i=11:scale
            if numbers(i)>number(1)
                number(1)=numbers(i);
                number=Adjust(1,10,number);
            end
        end      
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end
function[number]=Adjust(i,m,number)
    temp=number(i);
    j=2*i;
    while j<=m
        if j<m&&number(j)>number(j+1)
            j=j+1;
        end
        if number(j)>=temp
            break
        end
        number(i)=number(j);
        i=j;
        j=j*2;
    end
    number(i)=temp;
end
% function[number]=HeapSort(number,scale)
%     for i=scale:-1:2
%         temp=number(1);
%         number(1)=number(i);
%         number(i)=temp;
%         number=Adjust(1,i-1,number);
%     end
% end

实际表现:

取数据规模为100W,200W,300W,400W,500W作为测试数据,每个数据规模测试20组,记录平均运行时间,与插入排序相比,效率明显提升,如图13所示。

图13 规模为10的堆排序

测试一些大数据的运行时间(20组平均时间)如下:

一千万:0.0201s

五千万:0.1059s

一亿:0.2001s

五亿:1.0711s

十亿:4.6140s

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

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

相关文章

红黑树与234树

红黑树 参考&#xff1a;宇文新粥&#xff1a;红黑树红黑树可视化 234树 这个树有三种节点&#xff0c;分别包含1/2/3个元素&#xff0c;下方可以有2/3/4个子节点理解234树的插入 红黑树与234树之间的关系 红黑树有几个特性&#xff0c;但如果从234树的角度理解红黑树&…

在微软十年了!

时光飞逝&#xff0c;光阴如梭。 2013 年的 7 月 8 号&#xff0c;我在隔壁的交大软院毕业后&#xff0c;正式入职紫竹微软。 至今&#xff0c;已是整整 10 年了。 记得当时的闵行回市区的交通还不是那么堵&#xff0c;坐 5点半的班车下班&#xff0c;S4中环一路走&#xff0c;…

【C++ OJ练习】4.字符串中的第一个唯一字符

1.题目链接 力扣 2.解题思路 利用计数排序的思想 映射进行计数 最后计数为1的那个字符就是唯一字符 从前往后遍历 可以得到 第一个唯一字符 3.代码 class Solution { public:int firstUniqChar(string s) {//使用映射的方式统计次数 计数排序思想int count[26] { 0 };fo…

机器视觉硬件选型-工业光源-环形光源

视觉人机器视觉-硬件发货前硬件确认效果 工业光源根据灯的几何形状可分为条形光源,分区光源&#xff0c;环形光源、圆顶&#xff08;积分&#xff09;光源、平面光源&#xff0c;同轴光源&#xff0c;方形光源&#xff0c;线扫光源&#xff0c;点光源&#xff0c;线光源等等。 …

在上海滩,听懂5G时代的浪奔浪流

几天前的“湾区升明月”上&#xff0c;赵雅芝与吕良伟合唱了一首《上海滩》。“浪奔&#xff0c;浪流”的歌词一出&#xff0c;无数记忆涌上了一代人的心头。 上海这座城市&#xff0c;始终代表着进取、创新、引领&#xff0c;代表着面向世界的中国形象。黄浦江的浪花&#xff…

【尚医通】vue3+ts前端项目开发笔记 2 —— 创建项目、封装网络请求、集成elment-plus 、重置样式、准备状态管理/路由 等开发前准备

尚医通开发记录(Vue3TypeScriptPiniaAxios) 一、接口地址 服务器地址:http://syt.atguigu.cn 医院接口&#xff1a;http://139.198.34.216:8201/swagger-ui.html 公共数据接口&#xff1a;http://139.198.34.216:8202/swagger-ui.html 会员接口&#xff1a;http://139.198.34…

掌握文件转换的技巧:在线工具帮你轻松转换为PDF格式

许多文件都有自己的原始格式&#xff0c;然而这些格式都可以进行修改。遇到无法打开或信息丢失的情况时&#xff0c;可以进行格式转换&#xff0c;其中效果最好的就是PDF格式&#xff0c;无论在哪个平台上查看文档&#xff0c;都有自己的格式&#xff0c;能够在所有平台上查看的…

中国首个铝基轻量化平台?纯电中型 SUV 奇瑞eQ7将于7月12日发布

奇瑞新能源将于7月12日发布首台量产车奇瑞eQ7&#xff0c;并公布中国首个铝基轻量化平台。 车型参数&#xff1a;奇瑞 eQ7是一款定位纯电动中型SUV&#xff0c;采用后置后驱和油冷扁线三合一电机技术。其以全铝车身和全铝平台为基础&#xff0c;整备质量为185kg。车身尺寸为467…

表中签到ID格式是以逗号分隔,需将ID拆开并分成多条数据

原有数据格式&#xff1a; 拆分后数据格式&#xff1a; 拆分SQL: select bc.资源名称,bc.资源ID,bc.签到时间,bc.签到人,bb.column_value 签到附件ID from report_fir.V_kw_checksign_info bc,table(hbrmw6.split_string(bc.签到附件ID,,)) bb; HBRMW6.split_string函数创…

mysql数据库内存占用高原因(数据库内存占用高)

1、查看数据库分配内存大小 ( mysql内存计算器&#xff0c;具体地址为http://www.mysqlcalculator.com/ ) select VARIABLE_NAME,VARIABLE_VALUE/1024/1024 MB from information_schema.GLOBAL_VARIABLES WHERE VARIABLE_NAME in (key_buffer_size,query_cache_size,tmp_tabl…

基本数据与封装对象转换(Java)

文章目录 1. 基本数据与对象封装转换1.1 8种基本数据类型:1.2 基本数据类型 -- > 封装对象:1.3 封装对象 -- > 基本数据类型:1.4 借助String类型作为中间桥梁 2. 自动转换规则 1. 基本数据与对象封装转换 1.1 8种基本数据类型: boolean(true/false)&#xff0c;byte(1 …

时间序列预测 | Matlab粒子群算法(PSO)优化极限梯度提升树XGBoost时间序列预测,PSO-XGBoost时间序列预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列预测 | Matlab基粒子群算法(PSO)优化极限梯度提升树XGBoost时间序列预测,PSO-XGBoost时间序列预测模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码…

【雕爷学编程】Arduino动手做(153)---2.4寸TFT液晶触摸屏模块4

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

基于matlab使用激光雷达检测地平面和障碍物(附源码)

一、前言 此示例演示如何通过分割地平面并查找附近的障碍物来处理来自安装在车辆上的传感器的 3-D 激光雷达数据。这可以促进车辆导航的可驾驶路径规划。该示例还演示如何可视化流式激光雷达数据。 二、创建 Velodyne 文件读取器 本例中使用的激光雷达数据是使用安装在车辆上…

[工业互联-17]:常见EtherCAT主站与实现方法

目录 第1章 EtherCAT入门 1.1 简介 1.2 EtherCAT通信架构 第2章 EtherCAT主站方案 2.1 方案概述 2.2 主站配置步骤 2.3 EtherCAT主站软件 第3章 Windows操作系统支持EtherCAT的基本步骤 第4章 常见主站软件介绍&#xff1a;TwinCAT 4.1 简介 4.2 软件架构 4.3 应…

【计算机网络】第三章 数据链路层(概述 封装成桢 差错检错)

文章目录 第三章 数据链路层3.1 数据链路层概述3.2 封装成帧3.3 差错检测3.3.1 奇偶校验3.3.2 循环冗余校验 第三章 数据链路层 3.1 数据链路层概述 数据链路层是计算机网络体系结构中的一层&#xff0c;位于物理层和网络层之间。它负责在相邻节点之间传输数据&#xff0c;并提…

hugging face参数高效微调peft源码解析

大模型参数高效微调(PEFT) - 知乎 让天下没有难Tuning的大模型-PEFT技术简介 - 知乎 大模型参数高效微调技术原理综述&#xff08;三&#xff09;-P-Tuning、P-Tuning v2 - 知乎 你似乎来到了没有知识存在的荒原 - 知乎 大模型参数高效微调技术原理综述&#xff08;六&a…

由LM386构成的3W简易OCL功放电路/由TDA2009构成的1W高保真BTL功率放大器

由LM386构成的3W简易OCL功放电路 该电路是使用低功耗集成功率放大器 LM386 构成的 OCL 功放电路&#xff0c;电路结构简单&#xff0c;容易调试&#xff0c;非常适于自制。 一、电路工作原理 电路原理如图 31 所示。 图中IC1和IC2是两片集成功放LM386&#xff0c;接成OCL电路…

【编程的多线程学习-前章】什么是进程,PCB进程控制块抽象,cup分配,内存分配,虚拟地址,进程的通信,进程的意义

什么是进程 什么是进程/任务&#xff08;Process/Task&#xff09;进程就是一个运行起来的程序PCB 进程控制块抽象(PCB Process Control Block)pcb就是一个进程PCB具体包含的信息 CPU 分配 —— 进程调度&#xff08;Process Scheduling&#xff09;内存分配 —— 内存管理&…

Linux进度条小程序

文章目录 &#x1fa85;1. 回车换行♥1.1 回车♥1.2 换行 &#x1fa86;2. 缓冲区现象&#x1f9f8;3. 进度条实现♟3.1 逻辑♟3.2 进度条样式♟3.3 代码实现 &#x1f0cf;4. 场景使用 &#x1fa85;1. 回车换行 在学习C语言的时候&#xff0c;我们输出的时候&#xff0c;通常…