数据结构课程设计报告排序实验报告Word格式文档下载.docx
《数据结构课程设计报告排序实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告排序实验报告Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
![数据结构课程设计报告排序实验报告Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-12/18/547a84a8-498a-423a-afd5-ba24b872ee6d/547a84a8-498a-423a-afd5-ba24b872ee6d1.gif)
存储数据的线性表应为顺序存储。
三、数据结构设计
使用顺序表实现,有关定义如下:
typedefintStatus;
typedefintKeyType;
//设排序码为整型量
typedefintInfoType;
typedefstruct{//定义被排序记录结构类型
KeyTypekey;
//排序码
InfoTypeotherinfo;
//其它数据项
}RedType;
typedefstruct{
RedType*r;
//存储带排序记录的顺序表
//r[0]作哨兵或缓冲区
intlength;
//顺序表的长度
}SqList;
//定义顺序表类型
四、功能设计
(一)主控菜单设计
为实现通各种排序的功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
程序运行后,给出5个菜单项的容和输入提示,如下:
1.起泡排序
2.简单选择排序
3.希尔排序
4.直接插入排序
0.退出系统
(二)程序模块结构
由课题要求可将程序划分为以下几个模块(即实现程序功能所需的函数):
●主控菜单项选择函数menu()
●创建排序表函数InitList_Sq()
●起泡排序函数Bubble_sort()
●简单选择排序函数SelectSort()
●希尔排序函数ShellSort();
●对顺序表L进行直接插入排序函数Insertsort()
(三)函数调用关系
程序的主要结构(函数调用关系)如下图所示。
其中main()是主函数,它负责调用各函数。
进行调用菜单函数menu(),根据选择项0~4调用相应的函数。
main()函数使
for循环实现重复选择。
其循环结构如下:
for(;
;
)
{
longstart,end;
switch(menu())
{
case1:
printf("
*起泡排序*\n"
);
start=clock();
Bubble_sort(L);
end=clock();
%dms\n"
end-start);
fp=fopen("
D:
起泡排序.txt"
"
w"
if(fp==NULL)//打开文件失败
{
printf("
打开文件失败!
\n"
exit
(1);
}
for(i=1;
i<
=L.length;
i++)
fprintf(fp,"
%d"
L.r[i]);
fclose(fp);
break;
case2:
*简单选择排序*\n"
SelectSort(L);
直接插入排序.txt"
简单选择排序!
case3:
*希尔排序*\n"
ShellSort(L,an,14);
希尔排序.txt"
case4:
*直接插入排序*\n"
Insertsort(L);
case0:
\t退出!
return;
}
}
(四)文件结构
1、sort.h:
单链表相关的定义与声明
2、sort.cpp:
单链表运算的实现
3、menu.h:
主菜单函数的声明
4、menu.cpp:
主菜单函数的实现
5、mn.cpp:
主函数
(五)各函数的算法设计
1、InitList_Sq()
算法原理:
数组指针r指示线性表的基址,length指示线性表的当前长度,将随机生成的数赋给线性表,并生成相应文件。
流程图:
开始
申请存
随机生成30000个数字
生成文件
Fp=NULL
将顺序表打印到文件终止程序
关闭文件
结束
代码描述:
StatusInitList_Sq(SqList&
L)
{//构造一个线性表
FILE*fp;
L.r=(RedType*)malloc(LIST_INIT_SIZE*sizeof(RedType));
if(!
L.r)exit(OVERFLOW);
//存储分配失败
L.length=30001;
//表长度为30001
srand((unsigned)time(NULL));
for(inti=1;
L.r[i].key=rand()%30001+1;
fp=fopen("
构造一个线性表.txt"
if(fp==NULL)//打开文件失败
returnOK;
}//InitList_Sq
算法的时间复杂度分析:
O(n)
2.Bubble_sort()
每趟不断将记录两两比较,若发现逆序,则交换两个记录,使排序码较小的元素逐渐从后部移向前部(就象水底的气泡一样逐渐向上冒)。
voidBubble_sort(SqList&
{
RedTypex;
intn;
n=L.length;
//表长
for(inti=1;
i<
n;
i++)
{intflag=0;
//进入循环,清标志
for(intj=n-1;
j>
=i;
j--)
if(LT(L.r[j+1].key,L.r[j].key))
flag=1;
//有交换,置标志
x=L.r[j];
//L.r[j]←→L.r[j+1]
L.r[j]=L.r[j+1];
L.r[j+1]=x;
if(flag==0)break;
//若无交换则可结束冒泡排序
}
O(n2)
3、SelectSort()
第1趟:
从R[1]~R[n]中选取最小值,与R[1]交换;
第2趟:
从R[2]~R[n]中选取最小值,与R[2]交换;
第i趟:
从R[i]~R[n]中选取最小值,与R[i]交换;
………………………
第n-1趟:
从R[n-1]~R[n]中选取最小值,与R[n-1]交换.
共通过n-1趟,得到一个按排序码从小到大排列的有序序列
voidSelectSort(SqList&
{//对顺序表进行简单选择排序
L.length;
++i)
{//在L.r[i..L.length]中选择key最小的记录
intk=i;
for(intj=i+1;
j<
=L.length;
j++)
if(LT(L.r[j].key,L.r[k].key))k=j;
if(k!
=i){
x=L.r[i];
L.r[i]=L.r[j];
L.r[j]=x;
}
}//SelectSort
4、ShellInsert()
(1)、分组、组直接插入排序;
(2)、组数逐次减小;
(3)、组数=1,结束。
voidShellInsert(SqList&
L,intdk)
{//一趟Shell排序,dk为步长
inti;
for(i=dk+1;
{
if(LT(L.r[i].key,L.r[i-dk].key))
L.r[0]=L.r[i];
intj;
for(j=i-dk;
(j>
0)&
&
(LT(L.r[0].key,L.r[j].key));
j-=dk)
L.r[j+dk]=L.r[j];
L.r[j+dk]=L.r[0];
voidShellSort(SqList&
L,intdlta[],intt)
{//Shell排序,dlta[]为增量序列,t为增量个数
intk;
for(k=0;
k<
t;
k++)
ShellInsert(L,dlta[k]);
}//ShellSort
O(n(㏒2n)2)
5、Insertsort()
每步将一个待排序的对象,按其排序码大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。
在已形成的有序表中顺序查找,并在适当位置插入,把原来位置上的元素向后顺移。
voidInsertsort(SqList&
L)//对顺序表L进行直接插入排序
{for(inti=2;
if(LT(L.r[i].key,L.r[i-1].key))//需将L.r[i]插入有序表
{L.r[0]=L.r[i];
//复制为“哨兵”,暂存
for(intj=i-1;
LT(L.r[0].key,L.r[j].key);
j--)
L.r[j+1]=L.r[j];
//位置j指示了第一个key≤L.r[i].key的元素
L.r[j+1]=L.r[0];
//将暂存在r[0]中的记录插入到正确位置
//printf("
}
O(n2)
五、测试数据和结果
1、测试数据
随机产生30000个数
2、测试结果
本程序在VC++环境下实现,下面是对以上测试数据的运行结果。
(1)主菜单显示如下:
六、结束语
本设计完成了课题要求的任务,较熟练地掌握了各种排序方法。
在设计过程中,由于个别代码段设计不当多次出现程序溢出情况。
在评判各种排序方法的用时上换了两种计时方法,现在使用的这个较为准确。
从结果可以看出,堆排序和快速排序这两种方法最快。
当然或许还有更快的排序方法,此处没有使用并列举出来。