数据结构课程设计名: 基于EasyX的各排序算法的绝对执行时间的数据可视化
本设计涉及到对数据的随机初始化、数据的处理与可视化,文件的存取、求解11种排序方法的绝对执行时间、动态内存分配、C语言外库EasyX外库的使用。可移植性强、界面美观、初具小型系统雏形,是一份值得借鉴与学习的课程设计。
编译器:VisualStudio 2019
设计要求:
利用随机函数产生N个随机整数(2000以上),对这些数进行多种方法进行递增排序,采用11种排序方法实现上述问题求解(直接插入排序、折半插入排序、希尔排序、冒泡排序、改进冒泡排序、快速排序、选择排序、堆排序、归并排序、基数排序(桶排序)、计数排序),统计每一种排序方法的性能,求出每种算法所需要的绝对执行时间,并将得到的排序时间进行文件保存与数据可视化。
要求完成的主要任务:
1)利用随机函数产生初始化的随机整数(2000个以上);
2)对初始化数据进行多种方法的递增排序;
3)计算每种排序算法的绝对执行时间,并将数据保存为文件。
创新点:
(1)通过C语言外库EasyX实现数据可视化。让不同排序算法在不同的数据量下绝对执行执行时间有了更加直观生动的图像化表示。用散点图+折线图的方式让某一排序算法在数据量变化中体现其性能变化。
(2)通过矩阵来存储不同的算法在不同数据量下的绝对执行时间,并将其作为数据可视化与数据保存的源数据,将各种排序算法与数据量之间的执行时间通过一个矩阵来进行存储,是非常恰当的选择。极大地方便了数据存取与筛选。
优点:
(1)简洁美观,方便使用。
多次从用户使用角度出发,不断优化迭代程序,将功能选择权交给用户。如用户自主选择退出系统、用户非法输入的处理、返回子菜单、以及用户选择是否保存文件的选项等都是在保证正确运行的情况下将选择权交给用户。
(2)功能多样,不呆板。
十一种排序方法是核心功能,数据处理与可视化功能也是发挥着很大作用的。各排序算法得到的排序结果有专门的验证函数进行验证是否排序正确。数据可视化部分给出了查看方式与文件保存选择项。
系统文件结构图
排序算法模块图
主要数据结构:
根据本课程设计题目的要求,用于排序的序列数据结构采用数组进行存储,另外我还设计了对于各种排序算法在不同数据量下的绝对执行时间,使用数据结构中的矩阵来存储。
说明:为了多种类型数据能排序,数据类型定义为KeyType,默认为int。MaxSize为元素个数+1,因为考虑到堆排序的存储要求,所以需要加一。
(1)数组KeyType R[MaxSize]
用于存储所有通过随机数生成函数得到的数据。
(2)数组KeyType R1[MaxSize]
用于拷贝数组R中的数据和排序。考虑到排序方法对数组排序之后就会对数组造成了改变,为了保证在同一数据量下,每种排序方法都是使用的相同随机产生的序列,需要将R中的数据进行拷贝到R1中,让R1作为一个临时数组,在排序和拷贝赋值之间轮流变化,以保证每种排序方法都是对相同数据进行排序。
(3)矩阵EXETIME[11][10]
用于存储不同排序算法在不同数据量下的绝对执行时间。矩阵的每一行对应一种排序算法,一共有11中排序方法;矩阵的每一列对应一种待排序数据序列的数量,一共有10种,从10000-100000条依次递增10000条数据。
联系方式:
考虑到有一些读者想与笔者有进一步交流,笔者在这里贴一下本人的微信: StarsForMoon
,添加请说明来意(如CSDN)。
一、主要文件结构
说明:
① func.cpp:用于存放实现所有功能的函数(如菜单实现、各种排序函数的实现、数据输入与保存、数据展示)。
② main.cpp:负责启动系统,调用函数执行相应功能与终止系统,它是程序运行入口。
③ statement.h:函数的声明等。相当于是func.cpp的蓝图。
二、具体文件细节(部分)
(1)main.cpp源代码:
#pragma
#include"statement.h"
int main()
{
char cwd[256];
_getcwd(cwd, 256); //用于保存的图片的当前文件目录
double EXETIME[11][10]; //用于存储绝对执行时间的矩阵
int MaxSize = 10001; //数组元素最大个数
int j = 0; //列
double time; //绝对执行时间
for (MaxSize = 10001; MaxSize <= 100001; MaxSize += 10000)
{
//KeyType R[MaxSize], R1[MaxSize];
int* R = (int *)malloc(sizeof(int) * MaxSize);
int* R1 = (int *)malloc(sizeof(int) * MaxSize);
printf("随机产生%d个0-1000的整数,各种排序方法的比较\n", MaxSize - 1);
int n = MaxSize - 1;
printf("------------------------------------------------\n");
printf("排序方法 用时 结果验证\n");
printf("------------------------------------------------\n");
initial(R, 0, n); //产生R
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
int i = 0;
time=InsertSortTime(R1, n);
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time=BinInsertSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time=ShellSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time = BubbleSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n);
time = ImprovedBubbleSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time = QuickSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time = SelectSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy1(R, R1, n); //专门的拷贝函数,用于堆排序数组的复制 R[0..n-1]→R1[1..n]
time = HeapSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time = MergeSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time = CountingSortTime(R1, n);
i++;
EXETIME[i][j] = time;
copy(R, R1, n); //R[0..n-1]→R1[0..n-1]
time =RadixSortTime(R1, n);
i++;
EXETIME[i][j] = time;
printf("------------------------------------------------\n");
free(R1);
free(R);
j++;
}
bool system_key = 1;
while (system_key)
{
Select(EXETIME,&system_key,cwd); //对矩阵数据中的查看选择
}
return 1;
}
(2)statement.h源代码(部分):
void swap(KeyType& x, KeyType& y);
void initial(int R[], int low, int high); //产生R[low..high中的随机数
void copy(int R[], int R1[], int n); //用于排序数据复制
void copy1(int R[], int R1[], int n); //用于堆排序数据复制
bool test(KeyType R[], int low, int high); //验证排序结果的正确性
void InsertSort(KeyType R[], int n);
double InsertSortTime(KeyType R[], int n); //求直接插入排序的时间
void BinInsertSort(KeyType R[], int n);
double BinInsertSortTime(KeyType R[], int n); //求折半插入排序的时间
void ShellSort(KeyType R[], int n); //希尔排序算法
double ShellSortTime(KeyType R[], int n); //求希尔排序算法的时间
void BubbleSort(KeyType R[], int n);
double BubbleSortTime(KeyType R[], int n); //求冒泡排序算法的时间
void ImprovedBubbleSort(KeyType R[], int n);
double ImprovedBubbleSortTime(KeyType R[], int n); //求改进冒泡排序算法的时间
int partition(KeyType R[], int s, int t); //一趟划分
void QuickSort(KeyType R[], int s, int t); //对R[s..t]的元素进行快速排序
double QuickSortTime(KeyType R[], int n); //求快速排序算法的时间
void SelectSort(KeyType R[], int n);
double SelectSortTime(KeyType R[], int n); //求简单选择排序算法的时间
void sift(KeyType R[], int low, int high);
void HeapSort(KeyType R[], int n);
double HeapSortTime(KeyType R[], int n); //求堆排序算法的时间
void Merge(KeyType R[], int low, int mid, int high); //归并R[low..high]
void MergePass(KeyType R[], int length, int n); //对整个排序序列进行一趟归并
void MergeSort(KeyType R[], int n); //二路归并排序
double MergeSortTime(KeyType R[], int n); //求二路归并排序算法的时间
void CountingSort(KeyType R[],int n);
double CountingSortTime(KeyType R[], int n); //求计数排序算法的时间
int GetMax(KeyType R[], int n);
void RadixSort(KeyType R[], int n);
double RadixSortTime(KeyType R[], int n); //求基数排序算法的时间
void Picture(double Y[11],char *loc);//画图
void DataView(double Y[][10], int choice); //查看排序时间数据
void Visualize(double Y[][10], int choice,char *loc); //可视化排序时间数据
void SaveData(double EXETIME[][10], int row,int col); //保存所有数据
void Select(double Y[][10],bool *system_key,char *loc); //菜单选择
(3)func.cpp:
func.cpp则是对statement.h中声明的内容进行逐一实现。
func.cpp中各种实现功能的函数一览:
界面展示:
数据测试量为1万到10万,当数据量为10000时,各个排序算法绝对执行时间:
菜单展示
一些特色功能的展示
(1)各排序算法执行结果保存成文件
(2)数据可视化展示与保存
(3)任意一种排序算法各数据量下执行时间查看
当时这份课程设计是专业排名第一的分数,唯一的100分。
了解其他的更多内容,请直接添加我的VX:StarsForMoon
。
另外笔者还有另一个开发项目可供读者参考:Python结合机器学习的基于天气预报数据的数据分析与可视化课程设计项目,欢迎感兴趣的朋友交流学习~