数据结构 实验报告01

2023-05-16

一、实验目的和要求

完成尽可能多的数据排序,并显示运行时间。

二、实验环境

编译器:Vscode  DevC++ 

系统:Windows10

CPU:i5-8265U@1.60GHz

数据:int范围(排除桶排序,基数排序,计数排序)

三、实验内容

1. 选择合适的排序算法

2. 确定可排序数据长度最大值

3. 固定可排序数据内容

4. 显示运行时间

四、实验过程

4.1 任务定义和问题分析

当前任务分析:

1. 从什么方面去选择排序算法

2. 如何确定可排序数据大小的上限

3. 不同变量对实验的影响

 

问题分析:

  1. 对于排序算法的选择应从实验目的出发

为了处理尽可能多的数据  要求我们考虑数据很多时的情况

应选择时间,空间复杂度较小,足够稳定,能够在处理大数据时拥有较好的性能的算法

  1. 根据经验,首先确定一个大致范围,给设定上界(足够大,大到使算法崩溃)与下界(足够小,小到算法无障碍运行),然后利用二分来确定合适的边界
  2. 本实验的变量有数据集的大小,编译环境(不同编译器),不同排序算法,相同大小数据集的复杂程度(小数据可以进行设计,数据过大时无能为力,这就需要考虑算法的稳定性)。

4.2 数据结构的选择和概要设计

选择归并排序进行实验(内部实现还是依靠数组)

利用二分法来寻找数据上限(一步步逼近极限)

寻找足够多的变量进行对照实验  以期实验可靠性

 

4.3 详细设计

首先是进行对排序算法的选择 可以根据排序算法的时间复杂度和空间复杂来进行挑选

因为各种排序算法的对数据的存储处理手段大都为数组 所以空间复杂度均为O(n),故算法的挑选在于时间复杂度的不同。

下面是一个总的表格,大致总结了我们常见的所有的排序算法的特点。

排序法

平均时间

最差情形

稳定度

额外空间

备注

冒泡

O(n2)

    O(n2)

稳定

O(1)

n小时较好

交换

    O(n2)

    O(n2)

不稳定

O(1)

n小时较好

选择

O(n2)

O(n2)

不稳定

O(1)

n小时较好

插入

O(n2)

O(n2)

稳定

O(1)

大部分已排序时较好

基数

O(nlogRB)

O(nlogRB)

稳定

O(n)

B是真数(0-9)

R是基数(个十百)

Shell

O(nlogn)

O(ns) 1<s<2

不稳定

O(1)

s是所选分组

快速

O(nlogn)

O(n2)

不稳定

O(nlogn)

n大时较好

归并

O(nlogn)

O(nlogn)

稳定

O(1)

n大时较好

O(nlogn)

O(nlogn)

不稳定

O(1)

n大时较好

(表格取自网络)

 

以下为个人实际测试:(针对三个大小为100000的固定的随机数集)

(已忽略数据的读写时间)

排序算法

第一个数据集所花费时间

第二个数据集所花费时间

第三个数据集所花费时间

Bubblesort(冒泡排序)

54317ms

58288ms

61413ms

Insertsort(插入排序)

32999ms

28839ms

29197ms

Shellsort(希尔排序)

53ms

77ms

73ms

Heapsort(堆排序)

46ms

38ms

36ms

Quicksort(快速排序)

24ms

27ms

28ms

Mergesort(归并排序)

21ms

21ms

25ms

 

依据以上两个表格,可以得知最优选择应为归并排序

 

原因有以下几点:

  1. 时间复杂度小
  2. 算法足够稳定
  3. 对于n较大的情况更优

 

敲定排序算法后将进行对可排序数据大小的测试

 

测试思路:使用二分法来寻找极限值

 

目前以100000(10^5)为较小值,2147483647(2^31-1)为较大值进行二分

针对同样的数据集将进行六次统计时间  并求出平均值

实验细节:

考虑到实际等待算法运行完毕的时间还包括数据的读入和输出,因此对于数据的读入使用快速读入,输出则使用printf 来减少等待时间(1亿规模下,算法仅25s左右,而实际需要等待近1分钟)

由于数据过于庞大(且电脑还有其他占内存东西在运作),所以在打开输入输出文件时容易崩溃,解决方案有三个:1. 关闭其他程序   2.仅统计时间,不对处理后的数据进行输出  3.使用电脑自带的程序来打开文件并等待

当数据过于庞大时,随机输出数据也是十分耗时,于是要使用输出优化。

上面是我尝试造2147483647(2^31-1)大小的数据集  结果内存险些炸了(本人电脑办公本,内存较少的那种)这还是程序没有跑完 所以换了小数据10^9

结果打不开  无法检验  先行默认正确(毕竟多少给点面子,不过有待验证,因为2*10^9(2^31-1)比110GB要大,但缩减到原来的1/20  却仅剩下4.43GB)

Dev中具有报错,但程序依旧运行(不知道是卡死了  还是在运行)

(经过时间的检验   大概可以判定是卡死)

网上搜索后得知

意思就是int数组开大了,开int数组特别是二维数组需要注意不超过10^8.

经过逼近测试 边界值为498844223

(这个数加一数组就爆了)

带上数据读入所用的时间  比较可观:3分钟左右

五、测试及结果分析

对各种数据运行程序和算法的结果记录和分析,并对错误所作的修改和结果。

针对不同算法 同样大小(100000)的数据集 进行时间测定

排序算法

第一个数据集所花费时间

第二个数据集所花费时间

第三个数据集所花费时间

Bubblesort(冒泡排序)

54317ms

58288ms

61413ms

Insertsort(插入排序)

32999ms

28839ms

29197ms

Shellsort(希尔排序)

53ms

77ms

73ms

Heapsort(堆排序)

46ms

38ms

36ms

Quicksort(快速排序)

24ms

27ms

28ms

Mergesort(归并排序)

21ms

21ms

25ms

针对同样的数据集将进行六次统计时间  并求出平均值

(编译器为vscode)

数据集大小

10^8

(560MB)

2^31-1

10^9

5*10^8

……

498844223

(2GB)

1

25960

失败(造数据阶段就失败了)

失败(申请数组阶段失败)

失败(申请数组阶段失败)

失败(申请数组阶段失败)

111234

2

27346

104743

3

29321

105939

4

27045

104062

5

27274

105212

6

28546

104762

平均

27582

105992

(编译器为dev)各个数据集同上

数据集大小

10^8

560(MB)

2^31-1

10^9

5*10^8

……

498844223

(2GB)

1

29098

失败(造数据阶段就失败了)

失败(申请数组阶段失败)

失败(申请数组阶段失败)

失败(申请数组阶段失败)

108798

2

29098

106985

3

27878

109460

4

25959

107411

5

25737

105682

6

27930

104540

平均

27617

107162.7

        实验的最终结果是

归并排序所能排序的数据最大个数是498844223

所花费时间为:106s

5.1 实验数据

三个100000大小的数据在下面网站data文件内,各排序算法源码在source code 文件夹下

https://gitee.com/Nicet/Data-Structure/tree/master/The%20First%20Test%20

由于10^8的数据文件大小有539MB  暂无法上传

(当然了,大于10^8的498844223的数据文件有2.16GB  所以更是无法上传)

5.2 结果及分析

     我认为,实际算法是可以处理数据的最多不止到498844223  只不过本笔记本或编译器设置内存上限小。

        不过就实验过程来看   可以说结果就是498844223

        就和实验前面提到的这是数组在本机上可以申请到的最大值(int)

六、实验收获

分析数组大小时的收获

1. 函数内申请的变量,数组,是在栈(stack)中申请的一段连续的空间。栈的默认大小为2M或1M,开的比较小。

2. 全局变量,全局数组,静态数组(static)则是开在全局区(静态区)(static)。大小为2G,所以能够开的很大。

3. 而malloc、new出的空间,则是开在堆(heap)的一段不连续的空间。理论上则是硬盘大小。

实验过程有一个长达一天半的小插曲

在认为printf过慢是我调用了输出优化来生成数据  结果忘了输出元素之间的空格 导致程序卡死

下面当时我对这种奇异现象的实验报告描述

甚至我都连实验结果写了

这个是因为10^8之后的数据都忘了生成空格了  

而且由于数据庞大 无法打开检验   

直到看到10^8+1的数据大小比10^8的还要小的时候,我意识到了不对  

打开看了看  发现没有空格 才恍然大悟

翻工重做

边界数据:498844223

这才对------之前一直没有占据很大内存

不过  没多大会  数据变动成了

这下好了  cpu都不占用了   

不过耐心的我还是等了下去  

后来我把应用程序打开一看:

结束了已经跑出来结果了

七、参考文献

各种排序算法总结

C / C++ 计算程序运行的时间

超详细十大经典排序算法总结(java代码)c或者cpp的也可以明白

八、附录(源代码)

下面将贴上主要代码:

void Merge(int arr[], int aux[], int left, int mid, int right)

{

    int i = left;

    int j = mid + 1;

    int k = left;



    while (i <= mid && j <= right)

    {

        if (arr[i] > arr[j])

        {

            aux[k++] = arr[j++];

        }

        else

        {

            aux[k++] = arr[i++];

        }

    }

    while (i <= mid)

    {

        aux[k++] = arr[i++];

    }

    while (j <= right)

    {

        aux[k++] = arr[j++];

    }

    for (int i = left; i <= right; i++)

    {

        arr[i] = aux[i];

    }

}

void MergeSort(int arr[], int aux[], int left, int right)

{

    if (left < right)

    {

        int mid = left + (right - left) / 2;

        MergeSort(arr, aux, left, mid);

        MergeSort(arr, aux, mid + 1, right);

        Merge(arr, aux, left, mid, right);

    }

}

void MergeSort(int arr[], int length)

{

    clock_t start, end;

    start = clock();

    int *aux = new int[length];

    MergeSort(arr, aux, 0, length - 1);

    delete[] aux;

    end = clock();

    cout << end - start << "\n";

    // for (int i = 0; i < length; i++)

    //     printf("%d ", arr[i]);

}

以上是本实验所选算法--------归并排序

下面这个函数是本实验所选读入优化

void read(int &x)

{

    int f = 1;

    x = 0;

    char s = getchar();

    while (s < '0' || s > '9')

    {

        if (s == '-')

            f = -1;

        s = getchar();

    }

    while (s >= '0' && s <= '9')

    {

        x = x * 10 + s - '0';

        s = getchar();

    }

    x *= f;

}

下面这个函数是本实验为减少造数据时间所选的输出优化

void print(int x) 

{

    if (x > 9)

        print(x / 10);

    putchar(x % 10 + '0');

}

其余算法的code请移步到gitee上clone

很多图片上传失败   如果认为阅读有障碍 请移步到gitee上下载观看

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构 实验报告01 的相关文章

  • swift解析html

    最 近刚刚接触IOS开发 xff0c 在swift和OC之间纠结了很久 xff0c 不过对于一个java程序员来说 xff0c OC实在有些难以上手 xff0c 再看看swift xff0c 她就友好多了 xff0c 虽然现在大部分的App
  • 归并排序的迭代实现

    之前在另一篇文章中C 43 43 归并排序与快速排序详细分析了归并排序的递归实现 xff0c 但是会占用大量的时间和空间 xff0c 算法的效率低下 xff1b 使用迭代的方式代替递归的方式虽然比较难想 xff0c 但是会增大效率 如何写迭
  • java.lang.IllegalArgumentException异常解决

    在maven项目中测试代码的时候 xff0c 碰到java lang IllegalArgumentException 异常 xff1a 严重 Servlet service for servlet e3 manager in contex
  • Linux下的 command not found错误(解决方法)

    当我们在 Linux下执行一个命令时 xff0c 报 bash XXXX command not found xff0c 这和Windows是相同的道理 xff0c 都是环境变量惹的祸 xff0c 就是说你的 命令的 执行文件不在 usr
  • ubuntu18.04输入正确用户密码后黑屏并闪回登录界面解决方案

    过年离开实验室一会 xff0c 接了个向日葵远程控制 xff0c 连进来一不认识的 xff0c 然后工作站的cloudcompare打不开 xff0c 回来重启电脑之后开机一直循环登录界面 xff0c 没有办法进入任何一个用户的桌面 参考了
  • 小狼毫输入法的详细配置大全

    小狼毫输入法的详细配置大全 1 安装 在官网 https rime im download 下载并安装 这个路径有所有配置菜单的快捷方式 C ProgramData Microsoft Windows Start Menu Programs
  • 自我实现ArrayList

    面试者经常遇到集合类源码的问题 我们不求将所有的细节都记住 xff0c 但ArrayList与LinkedList比较 add get remove 扩容 及相关时间复杂度等核心思想要理解得一清二楚 ArrayList底层用数组实现 xff
  • 好博客要记录:JVM基础概念总结:数据类型、堆与栈、基本类型与引用类型

    JVM基础概念总结 xff1a 数据类型 堆与栈 基本类型与引用类型 Java虚拟机中 xff0c 数据类型可以分为两类 xff1a 基本类型和引用类型 基本类型的变量保存原始值 xff0c 即 xff1a 他代表的值就是数值本身 xff1
  • Future、FutureTask浅析

    Futurer多用于 耗时线程的计算 xff0c 主线程可以在完成自己的任务后 xff0c 再去查询该Future是否执行完毕并获取结果 他有一个回调函数protected void done xff0c 当任务结束时 xff0c 该回调函
  • 基于LinkedBlockingQueue源码自我实现阻塞队列

    LinkedBlockingQueue是一个阻塞的 线程安全的 由链表实现的双向队列 xff0c 和ArrayBlockingQueue一样 xff0c 是最普通也是最常用的阻塞队列 现基于LinkedBlockingQueue源码自我实现
  • AsyncTask原理详解

    在Android中 xff0c 异步执行是很重要的一块内容 xff0c 诸如网络请求 xff0c 大图片的加载 xff0c 等待等耗时操作都要在后台线程执行 xff0c 而这些操作又要通过UI线程来调用 xff0c 这样我们不得不需要通过异
  • LinearLayout和RelativeLayout的特殊属性

    Relativelayout属性 xff1a 属性名称描述android layout centerHorizontal水平居中android layout centerVertical垂直居中android layout centerIn
  • Activity launchmode和Intent flag详解

    学习安卓 xff0c 首先就要接触和学习Activity xff0c 想必大家在学习activity的过程中一定对activity的launchmode有过困惑 好在网络上关于activity launchmode的博客 解释一大堆 xff
  • 利用Canvas saveLayer手动绘制圆角View

    项目中包含了一个腾讯地图 xff0c 由于腾讯地图mapView不支持圆角背景 xff0c so决定自己画四个圆角view CornerView xff0c 覆盖在mapView上以实现圆角矩形的效果 要实现这样的效果 xff0c 需要重新
  • java内部类总结

    内部类是指在一个外部类的内部再定义一个类 类名不需要和文件夹相同 内部类可以是静态static的 xff0c 也可用public xff0c default xff0c protected和private修饰 xff08 而外部顶级类即类名
  • Linux服务器下Java环境配置-详细

    环境 xff1a Linux环境 具体步骤 xff1a 1 首先查看当前服务器环境是否已配置了JAVA 命令 xff1a java version 2 开始配置 通过官网下载JDK文件 xff0c 地址 xff1a https www or
  • 常用的Java文件操作

    span class hljs comment 1 创建文件夹 span span class hljs comment import java io span File myFolderPath 61 span class hljs bu
  • IntentFilter

    当Intent在组件间传递时 xff0c 组件如果想告知Android系统自己能够响应和处理哪些Intent xff0c 那么就需要用到IntentFilter对象 顾名思义 xff0c IntentFilter对象负责过滤掉组件无法响应和
  • 虚拟机集群关机脚本

    集群关机脚本 当我们使用虚拟机的数量过多时候 xff0c 一一关机未免显得太过麻烦 xff0c 所以这里设计了一个简单的Shell集群关机脚本 xff1a 这里以三台为例 xff1a Linux4 Linux3 Linux2 bin bas
  • Redis3.0集群crc16算法php实现方法(php取得redis3.0集群中redis数据所在的redis分区插槽,并根据分区插槽取得分区所在redis服务器地址)

    数据分区 Redis集群将数据分区后存储在多个节点上 xff0c 即不同的分区存储在不同的节点上 xff0c 每个节点可以存储多个分区 每个分区在Redis中也被称为 hash slot xff0c Redis集群中总共规划了16384个分

随机推荐

  • 安装 Google play service

    Be Careful Follow these steps and save your time Right Click on your Project Explorer Select New gt Project gt Android A
  • [计算机网络] - HTTP、HTTPS

    本文转载自 xff1a https blog csdn net qq 34827674 article details 104732605 1 HTTP 基本概念 HTTP 是超文本传输协议 xff0c 也就是HyperText Trans
  • ffmpeg命令行使用

    查看视频信息 ffmpeg i 视频名字 视频名字这里输入前几个字符按 tab 键可以自动补全 返回结果 xff1a 红框之内的内容没什么用 编码器 xff1a encoder Lavf57 25 100 持续时间 xff1a Durati
  • 基于JAVA的志愿者管理系统(最新)

    个人毕业设计 xff0c 喜欢的私聊 目录 基于JAVA的志愿者管理系统 3 专业 xff1a 学号 xff1a 学生姓名 xff1a 指导老师 xff1a 3 1 引言 4 1 1 项目开发的背景 4 1 2本文的主要工作 5 1 3本课
  • 追风筝的人:变质的友谊

    每个人心中都有一段不可言说的故事 在我们的岁月里 xff0c 那些朋友玩伴早已经消失在了我们的生活之中 但是那些共同的记忆还保留在我们的心中 追风筝的人 这是一本描述友谊的书籍 xff0c 能够给我们的心灵带来一丝的慰籍 哈桑在一次逃避中
  • 题目:判断101-200之间有多少个素数,并输出所有素数。

    题目 xff1a 判断101 200之间有多少个素数 xff0c 并输出所有素数 分析 xff1a 不能被2整除的称为质数 错解 xff1a for int i 61 101 i lt 61 200 i 43 43 if i 2 61 0
  • iOS总结

    1 设置UILabel行间距 NSMutableAttributedString attrString 61 NSMutableAttributedString alloc initWithString label text NSMutab
  • 最大公约数

    题目 xff1a 输入两个正整数m和n xff0c 求其最大公约数 分析 使用辗转相除法 竞相减损法 比如36和24的最大公约数是12 36 24 61 12 24 12 61 0 xff1b 所以12是36和24的最大公约数 比如48和3
  • SpringMVC中可以判断Controller中传来的参数是否为空方法

    package org swinglife controller import org springframework stereotype Controller import org springframework web bind an
  • HashMap的简单使用之remove的使用(三)

    remove方法可以删除其中的属性值
  • 新手最应该看的Mybatis中xml的分页查询sql语句

    研究了一整天 xff0c 终于弄明白了 Mybatis中 xml 的分页查询 sql 语句 xff1a lt 根据页数进行排序 gt lt select id 61 34 selectStudentByMap 34 resultType 6
  • 王昕的 java 下Excel的导入和导出,数据校验

    Apache POI是Apache开发的开源的跨平台的 Java API xff0c 提供API给Java程序对Microsoft Office格式档案进行各种操作 POI中Excel操作很简单 xff0c 主要类有 HSSFWorkboo
  • ModuleNotFoundError: No module named 'urllib2'

    历尽千辛万苦 xff0c 终于在Eclipse上安装好了python的编译工具了 https blog csdn net zrcshendustudy article details 82120397 正准备来一个爬虫程序入门的时候 xff
  • AttributeError: module 'pip' has no attribute 'pep425tags'

    情境再现 xff1a AttributeError module 39 pip 39 has no attribute 39 pep425tags 39 分析问题 xff1a 百度可知是Win32和Win64的输入命令各有所不同 解决问题
  • maven中的pom导入jackson包存在的问题,miss the jar

    情境再现 xff1a 之前导Jackson包的时候 xff0c 一直在dependency处有个错号 xff0c 我之前导的是2 6 0版本 分析问题 xff1a 网上好多说是maven文件没有删除的问题 后来看到有人导了不一样的版本 xf
  • java求完数的三种方法

    package al 64 author zhangrichao 64 version 创建时间 xff1a 2019年1月6日 下午8 55 34 求完数 第一种方法 xff1a 减法方式 public class PerfectNumb
  • 用java实现快速排序算法

    第一种方法 xff1a xff08 从数组右边开始 xff09 1 选择一个比较值c xff0c 以数组的第一个为例 2 从右边开始查找比c小的值 xff0c 再从左边开始查找比c大的值 xff0c 进行互换 3 当左边和右边同时指向一个值
  • Spring MVC常用注解

    一 Spring MVC 常用注解 1 64 RequestMapping Spring MVC 通过 64 RequestMapping 注解将 URL 请求与业务方法进行映射 xff0c 在控制器的类定义处以及方法定义处都可以添加 64
  • 字符串通配符(递归)

    题目描述 问题描述 xff1a 在计算机中 xff0c 通配符一种特殊语法 xff0c 广泛应用于文件搜索 数据库 正则表达式等领域 现要求各位实现字符串通配符的算法 要求 xff1a 实现如下2个通配符 xff1a xff1a 匹配0个或
  • 数据结构 实验报告01

    一 实验目的和要求 完成尽可能多的数据排序 xff0c 并显示运行时间 二 实验环境 编译器 xff1a Vscode DevC 43 43 系统 xff1a Windows10 CPU xff1a i5 8265U 64 1 60GHz