《数据结构与算法》实验和课程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 snsheap_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()

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

  1. 数据结构与算法:冒泡排序、插入排序、选择排序

    排序算法太多了,有很多可能你连名字都没听说过,比如猴子排序.睡眠排序.面条排序等.本文只众多排序算法中的一小撮,也是最经典的.最常用的:冒泡排序.插入排序.选择排序.归并排序.快速排序.计数排序.基数 ...

  2. 【经典算法学习-排序篇】直接选择排序

    一.选择排序 1.基本概念和介绍 选择排序的核心思想是:每一趟从无序区中选出关键字最小(或最大)的元素,按顺序放在有序区的最后(生成新的有序区,无序区元素个数减1),直到全部排完为止. 换句话说就是: ...

  3. 排序算法:冒泡排序、插入排序、选择排序、希尔排序

    相关博客: 排序算法:冒泡排序.插入排序.选择排序.希尔排序 排序算法:归并排序.快速排序 排序算法:桶排序.计数排序.基数排序 排序算法:堆排序 十大排序算法小结 一.冒泡排序: 1.算法原理: 冒 ...

  4. java 排序原理_简单选择排序算法原理及java实现(超详细)

    简单选择排序的原理 简单选择排序的原理非常简单,即在待排序的数列中寻找最大(或者最小)的一个数,与第 1 个元素进行交换,接着在剩余的待排序的数列中继续找最大(最小)的一个数,与第 2 个元素交换.以 ...

  5. JS 排序算法详解(冒泡排序,选择排序,插入排序,希尔排序,快速排序)

    JS 排序算法详解(冒泡排序,选择排序,插入排序,希尔排序,快速排序) 一. 大O表示法 在进行排序算法之前,我们得先掌握一种对算法效率的表示方法,大O表示法. 我们使用大O表示法来表示算法的时间复杂 ...

  6. 经典排序算法(一) —— Selection Sort 选择排序

    经典排序算法(一) -- Selection Sort 选择排序 文章目录 经典排序算法(一) -- Selection Sort 选择排序 简介 排序过程 实现 复杂度 简介 选择排序是一种简单直观 ...

  7. 排序算法系列之(一)——选择排序清新脱俗的一面

    · 前言 大家还记得我几个月前挖的一个大坑吗?非要自不量力的来讲讲排序家族的故事,这不是!今天我回来继续填这个坑,搞不好会把自己埋在这了/(ㄒoㄒ)/~~ 话说关于这些排序算法的总结网上各种版本的都有 ...

  8. java语言冒泡排序法_Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等...

    本文实现了八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序 首先是EightAlgorithms.java文件,代码如下: import jav ...

  9. 【Java】八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序 、快速排序、归并排序、堆排序和LST基数排序

    这篇文章主要介绍了Java如何实现八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序,需要的朋友可以参考下 本文实现了八个常用的排序算法:插入排序 ...

  10. 经典算法之冒泡排序法与直接选择排序法

    活动地址:21天学习挑战赛 文章目录 一.冒泡排序法 1.基本思想 2.算法步骤 3.代码实践 4.复杂度分析 二.直接选择排序法 1.基本思想 2.算法步骤 3.代码实践 4.复杂度分析 一.冒泡排 ...

最新文章

  1. 关于内层DIV设置margin-top不起作用的解决方案
  2. python发邮件给女朋友代码_python发邮件的代码
  3. 浅析设计模式(三)——抽象工厂模式
  4. Java VS Go,微服务究竟谁更快?
  5. OSChina 周五乱弹 —— 姑娘馋的口水都留下来了。
  6. oracle添加男女约束,Oracle如何给数据库添加约束过程解析
  7. 地图上如何量方位角_野外怎样确定方位 户外辨别方向和位置的方法有哪些?...
  8. 多省市房屋交易平台引入电子签章推动住房交易合同网签备案
  9. Java实现 LeetCode 313 超级丑数
  10. 关于B树的思考:m阶B树的非根非叶节点为什么要至少为ceil(m/2)个孩子? c/c++描述
  11. Ubuntu 14.04(64位)安装和使用docker
  12. Android动画总结系列(2)——补间动画使用
  13. windows10自带视频录制器
  14. 信息安全之访问控制策略
  15. 2021年广西甘蔗播种面积、产量及进口情况分析:广西甘蔗产量占全国甘蔗总产量的68.56%[图]
  16. JZOJ3481. 【NOIP2013模拟10.23】君と彼女の恋(2017.10B组)
  17. matlab 矩阵 幂运算符,matlab矩阵的乘方power运算
  18. orb-slam3安装编译运行。opencv3.2 undefined reference to `cblas_zgemm vgg_generated_48.i ippicv_linux_20151
  19. 史上最全SpringBoot学习笔记-动力节点王鹤(2021最新版)
  20. 25页国有企业数字化转型ppt,解决4个典型痛点场景,实现提质增效

热门文章

  1. 心之所向,百炼成钢 第一章
  2. python爬虫爬取网页信息
  3. redis-shiro session 共享subject中principal 为空
  4. 如是言,一个关于格言的故事
  5. 纯CSS实现抖音3D酷炫旋转相册
  6. 国内的人工智能神经网络研究院有哪些
  7. Google Map 开发笔记——基础篇(Javascript )
  8. 开发、测试、测试开发
  9. Puddings收获
  10. 【opensource】开源网址推荐