《数据结构与算法》实验:排序算法实验比较——选择排序 & 堆排序

2023-11-09

《数据结构与算法》实验和课程Github资源 

《数据结构与算法》实验:线性结构及其应用——算术表达式求值

《数据结构与算法》实验:树型结构的建立与遍历

《数据结构与算法》实验:图结构的建立与搜索

《数据结构与算法》实验:查找结构的实验比较——二叉查找树BST & 二分(折半)查找

《数据结构与算法》实验:排序算法实验比较——选择排序 & 堆排序

《数据结构与算法》实验报告

学生姓名

郭茁宁

院(系)

计算机科学与技术

  

1183710109

 

软件工程

实验时间

2019年12月27日(周五)

实验地点

格物213室

实验项目

实验/5-5排序算法实验比较(4学时)

实验目的:将课程的基本原理、技术和方法与实际应用相结合,训练和提高学生组织、存储和处理信息的能力,以及复杂问题的数据结构设计能力和程序设计能力,培养软件设计与开发所需要的实践能力。

实验要求:灵活运用基本的数据结构和算法知识,对实际问题进行分析和抽象;结合程序设计的一般过程和方法为实际问题设计数据结构和有效算法;用高级语言对数据结构和算法进行编程实现、调试,测试其正确性和有效性。

实验内容:排序算法的实现与实验比较

     实现一组经典的排序算法,通过实验数据的设计,考察不同规模和分布的数据对排序算法运行时间影响的规律,验证理论分析结果的正确性。

1 实现以下三组排序方法中的一组排序算法:

1)冒泡排序和快速排序;

2)插入排序和希尔排序;

3)选择排序和堆排序。

2 产生不同规模和分布的数据,以“图或表”的方式给出输入规模和分布对排序方法运行时间变化趋势的影响(画出T(n)的曲线)。并与理论分析结果比较。

3 将上述“图或表”采用图片等形式贴在实验报告中,与作适当分析或说明。

数据结构定义:

数组:存放读入元素,用于选择排序

堆:最小堆,用于堆排序

#define N 1000000

int a[N + 5];

算法设计与分析(要求画出核心内容的程序流程图):

  1. 选择排序:

从小到大排序时,排到第i个位置时,应该选择第i+1到第n个位置上最小的元素放在这个位置。在实际编程中,为了不另外开数组空间,在放置位置时,采用“与该位置原本的元素交换”的方法。

void SelectSort(int n)

{

    int mini;

    for (int i = 1; i < n; i++)

    {

        mini = i;

        for (int j = i + 1; j <= n; j++)

            if (a[j] < a[mini]) mini = j;

        if (i != mini) Swap(i, mini);

    }

    printf("SelectSort:\n");

}

  1. 堆排序:

建堆:

从堆的底层开始建立,保证建立第i层时,第i+1到logN层的元素都满足根节点元素小于其子结点元素,最后整个堆的根节点是整个堆的最小值。

取最小值:

每次取处堆的根结点,然后和任意一个叶子结点交换,并从上到小调整堆。

void HeapAdjust(int x, int n) //调整堆

{

    if (x * 2 > n) return;

    int maxi = x * 2 + 1 > n ? x * 2 : (a[x * 2< a[x * 2 + 1? x * 2 : x * 2 + 1);

    if (a[maxi] < a[x]) Swap(x, maxi), HeapAdjust(maxi, n);

}

void HeapSort(int n)

{

    for (int i = n; i >= 1; i--HeapAdjust(i, n); //建立最小堆

    for (int i = n; i > 1; i--)

    {

        Swap(1, i); //取出堆根节点

        HeapAdjust(1, i - 1); //调整堆,此时大小减1

    }

}

 

实验测试结果及结果分析:

Heap1 0.017200s

Heap2 0.020300s

Heap3 0.018800s

Heap4 0.020300s

Heap5 0.020300s

Select1 1.626500s

Select2 1.096900s

Select3 1.067200s

Select4 1.157800s

Select5 1.067200s

示例为100000规模数据,在测试中,每一个规模测试5组数据,舍弃偶然误差,取平均值,进行统计分析。

sta = GetTickCount();

for (int i = 1; i <= M; i++HeapSort(n);

end = GetTickCount();

 

printf("Heap%d %.6lfs\n", j, (double)(end - sta) / 1000 / M);

 

左纵轴、水绿色是堆排序时间,右纵轴、紫色是选择排序时间;

可以从图中看出选择排序的时间曲线是2次函数的曲线,增长速度远超希尔排序的NlogN曲线。

问题及解决方法:

  1. 时间数据存在偏差——多组数据进行平均;
  2. 一组数据排序好后再排序不具有典型性——同一规模多组不同分布;
  3. 两种排序时间数据差别太大——用不同尺度坐标轴

源程序名称:lab5.cpp

注意:正文文字为宋体小4号,图中文字为宋体5号。行距为多倍行距1.25。

      源程序与此报告打包提交,压缩包采用学号命名。

// lab5.cpp

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
#define Swap(x, y) (a[x] = a[x] ^ a[y], a[y] = a[x] ^ a[y], a[x] = a[x] ^ a[y])
#define N 1000000
int a[N + 5];

void HeapAdjust(int x, int n) //调整堆
{
    if (x * 2 > n) return;
    int maxi = x * 2 + 1 > n ? x * 2 : (a[x * 2] < a[x * 2 + 1] ? x * 2 : x * 2 + 1);
    if (a[maxi] < a[x]) Swap(x, maxi), HeapAdjust(maxi, n);
}

void HeapSort(int n)
{
    for (int i = n; i >= 1; i--) HeapAdjust(i, n); //建立最小堆
    for (int i = n; i > 1; i--)
    {
        Swap(1, i); //取出堆根节点
        HeapAdjust(1, i - 1); //调整堆,此时大小减1
    }
}

void Print(int n)
{
    for (int i = 1; i < n; i++) printf("%d ", a[i]);
    printf("%d\n\n", a[n]);
}

void SelectSort(int n)
{
    int mini;
    for (int i = 1; i < n; i++)
    {
        mini = i;
        for (int j = i + 1; j <= n; j++)
            if (a[j] < a[mini]) mini = j;
        if (i != mini) Swap(i, mini);
    }
}

#define M 10
int main()
{
    freopen("init.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    DWORD sta, end;
    scanf("%d", &n);
    for (int j = 1; j <= 5; j++)
    {
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        sta = GetTickCount();
        for (int i = 1; i <= M; i++) HeapSort(n);
        end = GetTickCount();
        printf("Heap%d %.6lfs\n", j, (double)(end - sta) / 1000 / M);
    }
    for (int j = 1; j <= 5; j++)
    {
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        sta = GetTickCount();
        SelectSort(n);
        end = GetTickCount();
        printf("Select%d %.6lfs\n", j, (double)(end - sta) / 1000 / M);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
// create_data.cpp

#include <cstdio>
#include <cstdlib>
#define N 100000
#define M (1 << 30)
int main()
{
    freopen("init.txt", "w", stdout);
    printf("%d\n", N);
    for (int j = 1; j <= 5; j++, printf("\n"))
        for (int i = 1; i <= N; i++)
        {
            int x = rand() % M + 1, y = rand() % 15;
            x = x << y;
            printf("%d ", x);
        }
    fclose(stdout);
    return 0;
}
# d.py 画图

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

heap_n = [10000, 50000, 100000, 200000, 300000]
heap_t = [0.001575, 0.008575, 0.016, 0.03555, 0.051975]
slct_n = [10000, 50000, 100000, 200000, 300000]
slct_t = [0.01095, 0.257425, 1.054325, 4.168375, 9.321475]

plt.rcParams["figure.figsize"] = (10.0, 6.0)
fig = plt.figure()
style = ["darkgrid", "dark", "white", "whitegrid", "ticks"]
sns.set_style(style[2])

ax1 = fig.add_subplot(111)
ax1.set_ylim([0, 1])
ax1.plot(heap_n, heap_t, "c", ms=10, lw=1, marker="o")  # 设置线粗细,节点样式
ax1.set_ylabel("Heap_time", fontsize="20")
ax1.tick_params(labelsize=10)
for x, y in zip(heap_n, heap_t):  # # 添加数据标签
    plt.text(
        x, y + 0.01, str(y) + "s", ha="center", va="bottom", fontsize=8, rotation=0
    )
# plt.plot(heap_t, label="heap")
# plt.legend(bbox_to_anchor=(0.15, 1.0))

ax2 = ax1.twinx()
ax2.set_ylim([0, 10])
ax2.plot(slct_n, slct_t, "darkviolet", ms=7, lw=1, marker="o")  # 设置线粗细,节点样式
ax2.set_ylabel("Select_time", fontsize="20")
ax2.tick_params(labelsize=10)
for x, y in zip(slct_n, slct_t):  # # 添加数据标签
    plt.text(x, y + 0.1, str(y) + "s", ha="center", va="bottom", fontsize=8, rotation=0)
# plt.plot(slct_t, label="slct")
"""
plt.legend(
    bbox_to_anchor=(0.0, 1.02, 1.0, 0.102),
    loc=0,
    ncol=3,
    mode="expand",
    borderaxespad=0.0,
)
"""
plt.savefig(r"D:\GZN\HIT\个人文件\2019秋数据结构与算法\Lab5\1.png", dpi=1000, bbox_inches="tight")
plt.grid()
plt.show()

 

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

《数据结构与算法》实验:排序算法实验比较——选择排序 & 堆排序 的相关文章

  • 在java程序中使用c++ Dll

    我正在尝试使用System LoadLibrary 使用我用 C 编写的一个简单的 dll UseDllInJava java import com sun jna Library import com sun jna Native imp
  • 如何使用 zlib 制作 .zip 文件

    我正在阅读zlib的文档 它相当详细 但我读到了这一行 输出数据将位于zlib格式 与 gzip 或zip formats http www zlib net zlib how html http www zlib net zlib how
  • 在 C# 中生成 HMAC-SHA1

    我正在尝试使用 C 来使用 REST API API 创建者提供了以下用于 hmac 创建的伪代码 var key1 sha1 body var key2 key1 SECRET KEY var key3 sha1 key2 var sig
  • 如何尝试/捕获所有异常

    我正在完成由其他人启动的 UWP 应用程序 该应用程序经常崩溃 我总是陷入困境应用程序 at if global System Diagnostics Debugger IsAttached global System Diagnostic
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • C++中delete和delete[]的区别[重复]

    这个问题在这里已经有答案了 可能的重复 C 中的删除与删除 运算符 https stackoverflow com questions 2425728 delete vs delete operators in c 我写了一个包含两个指针的
  • 从 C 结构生成 C# 结构

    我有几十个 C 结构 我需要在 C 中使用它们 典型的 C 结构如下所示 typedef struct UM EVENT ULONG32 Id ULONG32 Orgin ULONG32 OperationType ULONG32 Size
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • 为什么具有相同名称但不同签名的多个继承函数不会被视为重载函数?

    以下代码片段在编译期间产生 对 foo 的调用不明确 错误 我想知道是否有任何方法可以解决此问题而不完全限定对 foo 的调用 include
  • 使用 mingw32 在 Windows 上构建 glew 时“DllMainCRTStartup@12”的多个定义

    我关注了这个主题 使用 mingw 使建筑物在 Windows 上闪闪发光 https stackoverflow com questions 6005076 building glew on windows with mingw 6005
  • 从 Delphi 调用 C# dll

    我用单一方法编写了 Net 3 5 dll 由Delphi exe调用 不幸的是它不起作用 步骤 1 使用以下代码创建 C 3 5 dll public class MyDllClass public static int MyDllMet
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • 为什么文件更新时“如果较新则复制”不复制文件?

    我在 Visual Studio Express 中有一个解决方案 如下所示 The LogicSchemaC 中的类 将在运行时解析指定的 XML 文件 以下是在main的方法Program cs LogicSchema ls new L
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是
  • 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同

    System Net WebException 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同 在 System Net FtpWebRequest CheckError 在 System Net FtpWebReque
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率

随机推荐

  • java jdbc 故障转移,MySQL JDBC连接上的故障转移?

    I am trying to determine how i could implement a high availablity solution using the MySQL JDBC driver it seems that the
  • 最全的Java笔试题库之选择题篇-总共234道【121~180】

    121 EJB的优点有哪些 选择2项 A 技术领先 B 价格低廉 C 性能优越 D 强大的容器支持 解答 CD 122 以下哪些接口能够实现对Web访问者的身份认证 选择1项 A Http Servlet Request B Http Se
  • Linux用户切换到root后运行图形程序报错(*GLib-GIO-CRITICAL **)

    用su切换到root用户后 运行某些带图形的程序 会报如下错误 ImageProc qt 3158 GLib GIO CRITICAL g dbus connection register object assertion G IS DBU
  • iOS进阶_密码学(二.钥匙串访问)

    网络开发中的原则 在网络上不允许传输用户的明文隐私数据 在本地不允许保存用户的明文隐私数据 类似于QQ 微信的记住密码 在客户端本地保存用户加密后的密码 NSUserDefaults 明文保存才能反算 能够反算的算法 钥匙串访问 开放给开发
  • Fortran 微分方程求解 --ODEPACK

    最近涉及到使用Fortran对微分方程求解 我们知道MATLAB已有内置的函数 比如ode家族 ode15s 对应着不同的求解办法 通过查看odepack的官方文档 我尝试使用了dlsode求解刚性和非刚性常微分方程组 首先是github网
  • Unity3d防止按键劫持导致无法响应点击事件

    起因 项目上线之后 接到一些玩家反馈 在登录界面点击没有响应 无法登陆的 小米 魅族等应用商店上的差评也大多集中于此 心里一万只草泥马在奔腾 排查问题 首先 排查逻辑代码 找出是谁写的代码 大概会被拿去祭天吧 然而并没有 逻辑代码并没有问题
  • FastCGI处理自定义HTTP头

    FCGX中 自定义头可以获取环境变量获得 但是名字前面要加入HTTP 字母全部大写 例如 自定义头username 在fastcgi的FCGX中 变为 HTTP USERNAME 可以用FCGX GetParam获取单个环境变量 头信息在F
  • 使用高德地图(点标记)完成vue2项目

    目录 前言 官网中的代码 项目中的代码 效果图 代码 配置 前言 由于项目 中有要使用高德地图的需求 我就 傲娇的说 我会使用百度地图 可以改为百度地图不 最终的结果就是要用高德地图 后端小哥哥还特别好的安慰我说 高德地图的用法跟百度地图的
  • 上采样和下采样

    分辨率 是屏幕图像的精密度 是指显示器所能显示的像素的多少 由于屏幕上的点 线和面都是由像素组成的 显示器可显示的像素越多 画面就越精细 同样的屏幕区域内能显示的信息也越多 可以把整个图像想象成是一个大型的棋盘 而分辨率的表示方式就是所有经
  • c#笔记2018-12-27

    using System 2018 12 27 c 学习笔记 1 c 判断if else if switch 2 循环while for do while 3 循环实例 for循环99乘法表 while 循环99乘法表 do while 循
  • 关于contenteditable = true中光标异常判定的解决方法

  • Eclipse和PyDev搭建完美Python开发环境(Windows篇)

    十一长假在家闲着没事儿 准备花点时间学习一下Python 今儿花了一个下午搭建Python的开发环境 不禁感叹 开源的东西就是麻烦啊 唉 可怜我们这些被微软宠坏了的开发人员 为什么不用别的IDE呢 IDLE是小打小闹用的 那个WingIDE
  • 如何选用GPU云服务器?

    1 相关知识了解 1 1 了解厂家 1 1 1 面向个人的平台 名称 特点 极链AI云 微信绑定送100 学生200 1024Lab云 便宜 国外 DBC支付 不知道是啥 不考虑 矩池云GPU VNC远程访问图形化桌面 操作简单 gpu种类
  • ls命令用法总结

    ls 命令可以说是linux下最常用的命令之一 a 列出目录下的所有文件 包括以 开头的隐含文件 b 把文件名中不可输出的字符用反斜杠加字符编号 就象在C语言里一样 的形式列出 c 输出文件的 i 节点的修改时间 并以此排序 d 将目录象文
  • idea的target文件夹不见了

    1 第一种方法 在2位置打上 2 第二种方法 在5里面寻找target 并删掉 3 总结 目前遇到的就这两种情况 第二种情况5中用 分开的每一个都是忽略的文件或文件夹 像 git文件 idea文件夹都可以在这里配置忽略 我知道的作用是在pr
  • Unity Xbox360 Input

    1 资料收集 2 Unity中增加键值注册 3 A键值 4 B键值 5 X键值 6 Y键值 7 LeftBumper 键值
  • 思考卷积神经网络(CNN)中各种意义

    只是知道CNN是不够 我们需要对其进行解剖 继而分析不同部件存在的意义 CNN的目的 简单来说 CNN的目的是以一定的模型对事物进行特征提取 而后根据特征对该事物进行分类 识别 预测或决策等 在这个过程里 最重要的步骤在于特征提取 即如何提
  • AltiumDesigner 绘制PCB常见问题

    1 普通过孔16mil 24mil 2 PCB双层板看到上面有大量的过孔 很多都没有用到的 这些过孔有什么用啊 答 通过大量过孔连接顶层和底层的铺铜 也就是将顶层和底层的 地 良好的连接 为接地点提供更多回路 以提高整个电路板的抗干扰能力
  • Rpm相关操作

    安装rpm包 rpm ivh your package rpm 安装过程中可能出现下面的警告或者提示 conflict with 可能是要安装的包里有一些文件可能会覆盖现有的文件 缺省时这样的情况下是无法正确安装的 强制安装即可 rpm f
  • 《数据结构与算法》实验:排序算法实验比较——选择排序 & 堆排序

    数据结构与算法 实验和课程Github资源 数据结构与算法 实验 线性结构及其应用 算术表达式求值 数据结构与算法 实验 树型结构的建立与遍历 数据结构与算法 实验 图结构的建立与搜索 数据结构与算法 实验 查找结构的实验比较 二叉查找树B