排序实验报告.docx

上传人:b****8 文档编号:10989089 上传时间:2023-02-24 格式:DOCX 页数:27 大小:322.73KB
下载 相关 举报
排序实验报告.docx_第1页
第1页 / 共27页
排序实验报告.docx_第2页
第2页 / 共27页
排序实验报告.docx_第3页
第3页 / 共27页
排序实验报告.docx_第4页
第4页 / 共27页
排序实验报告.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

排序实验报告.docx

《排序实验报告.docx》由会员分享,可在线阅读,更多相关《排序实验报告.docx(27页珍藏版)》请在冰豆网上搜索。

排序实验报告.docx

排序实验报告

《数据结构》

课程设计报告

 

专业计算机科学与技术

班级

姓名

学号

指导教师

起止时间2012.12~2013.1

课程设计:

排序综合

一、任务描述

排序综合

任务:

利用随机函数产生n个随机整数(20000以上),对这些数进行多种方法进行排序。

要求:

(1)至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。

并把排序后的结果保存在不同的文件中。

(2)统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。

二、问题分析

1、功能分析

分析设计课题的要求,要求编程实现以下功能:

(1)排序表的建立—即创建顺序表;

(2)顺序表的排序—即直接插入排序、希尔排序、起泡排序、快速排序、简单选择排序操作;

(3)统计每一种排序方法的性能—即测试上机运行程序所花费的时间;

2、数据对象分析

数据信息:

随机整数

数据数量可以预先确定(20000以上)

三、数据结构设计

使用顺序表实现,有关定义如下:

typedefintStatus;

typedefintKeyType;//设排序码为整型量

typedefintInfoType;

typedefstruct{//定义被排序记录结构类型

KeyTypekey;//排序码

InfoTypeotherinfo;//其它数据项

}RedType;

typedefstruct{

RedType*r;//存储带排序记录的顺序表

//r[0]作哨兵或缓冲区

intlength;//顺序表的长度

}SqList;//定义顺序表类型

四、功能设计

(一)主控菜单设计

为实现通各种排序的功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。

程序运行后,给出6个菜单项的内容和输入提示,如下:

1.直接插入排序

2.希尔排序

3.起泡排序

4.快速排序

5.简单选择排序

0.退出系统

(二)程序模块结构

由课题要求可将程序划分为以下几个模块(即实现程序功能所需的函数):

●主控菜单项选择函数menu()

●创建排序表函数InitList_Sq()

●对顺序表L进行直接插入排序函数Insertsort()

●希尔排序函数ShellSort();

●起泡排序函数Bubble_sort()

●快速排序函数QSort()

●简单选择排序函数SelectSort()

(三)函数调用关系

程序的主要结构(函数调用关系)如下图所示。

Menu()InitList_Sq(L)

Main()

Insertsort(L)ShellSort()Bubble_sort()QSort()SelectSort()

其中main()是主函数,它进行菜单驱动,根据选择项0~5调用相应的函数。

main()函数使用for循环实现重复选择。

其循环结构如下:

for(;;)

{

longstart,end;

switch(menu())

{

case1:

printf("*直接插入排序*\n");

start=clock();

Insertsort(L);

end=clock();

printf("%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:

printf("*希尔排序*\n");

start=clock();

ShellSort(L,an,14);

end=clock();

printf("%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;

case3:

printf("*起泡排序*\n");

start=clock();

Bubble_sort(L);

end=clock();

printf("%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;

case4:

printf("*快速排序*\n");

start=clock();

QSort(L,0,L.length);

end=clock();

printf("%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;

case5:

printf("*简单选择排序*\n");

start=clock();

SelectSort(L);

end=clock();

printf("%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;

case0:

printf("\t退出!

\n");

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;i<=L.length;i++)

L.r[i].key=rand()%30001+1;

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);

returnOK;

}//InitList_Sq

算法的时间复杂度分析:

O(n)

2、Insertsort()

算法原理:

每步将一个待排序的对象,按其排序码大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。

在已形成的有序表中顺序查找,并在适当位置插入,把原来位置上的元素向后顺移。

流程图:

开始

i=2

i

L.r[i].key

L.r[0]=L.r[i]

j=i-1

L.r[0].key

L.[j+1]=L.r[j]

j--

L.r[j+1]=L.r[0]

i++

结束

代码描述:

voidInsertsort(SqList&L)//对顺序表L进行直接插入排序

{for(inti=2;i<=L.length;i++)

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]中的记录插入到正确位置

}}

算法的时间复杂度分析:

O(n2)

3、ShellInsert()

算法原理:

1、分组、组内直接插入排序;2、组数逐次减小;3、组数=1,结束。

流程图:

开始

i=dk+1

i

L.r[i].key

L.r[0]=L.r[i]

j=i-dk

(j>0)&&(LT(L.r[0].key,L.r[j].key)否

L.r[j+dk]=L.r[j]

j-=dk

L.r[j+dk]=L.r[0]

i++

结束

代码描述:

voidShellInsert(SqList&L,intdk)

{//一趟Shell排序,dk为步长

inti;

for(i=dk+1;i<=L.length;i++)

{

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];

}

}

}

4、

ShellSort()

流程图:

开始

k=0

k

ShellInsert(L,dlta[k])

k++

结束

代码描述:

voidShellSort(SqList&L,intdlta[],intt)

{//Shell排序,dlta[]为增量序列,t为增量个数

intk;

for(k=0;k

ShellInsert(L,dlta[k]);

}//ShellSort

算法的时间复杂度分析:

O(n(㏒2n)2)

5、Bubble_sort()

算法原理:

每趟不断将记录两两比较,若发现逆序,则交换两个记录,使排序码较小的元素逐渐从后部移向前部(就象水底的气泡一样逐渐向上冒)。

流程图:

开始

n=L.length

i=1

i

flag=0

j=n-1

j<=i

L.r[j+1].key

flag=1

L.r[j]←→L.r[j+1]

j--

flag=0

i++

结束

代码描述:

voidBubble_sort(SqList&L)

{

RedTypex;

intn;

n=L.length;//表长

for(inti=1;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)

6、Partition()

算法原理:

从n个待排记录中任取一个记录Ri作标准,调整序列中各个记录的位置,使得:

排在ri前的记录排序码<=ri.key排在ri后的排序码,该过程为一趟快速排序。

这样就确定了Ri在序列中的最终位置,同时将序列分成两个子序列。

流程图:

开始

L.r[0]=L.r[low]

Pivotkey=L.r[low].key

Low

low=pivotkey否

--high

L.r[low]←→L.r[high]

 

low

++low

L.r[low]←→L.r[high]

L.r[low]=L.r[0]

returnlow

结束

代码描述:

intPartition(SqList&L,intlow,inthigh){

/*交换子表r[low…high]的记录,使枢轴记录到位,并返回其位置。

返回时,在枢轴之前的记录排序码均不大于其排序码,之后的记录排序码均不小于其排序码。

*/

L.r[0]=L.r[low];//以子表的首记录作为枢轴,放入r[0]单

intpivotkey;

pivotkey=L.r[low].key;//取枢轴的排序码存入pivotkey变量

while(low

RedTypex;

RedTypet;

while(low=pivotkey)--high;

x=L.r[low];

L.r[low]=L.r[high];

L.r[high]=x;//将比枢轴排序码小的记录交换到低端

while(low

t=L.r[high];

L.r[high]=L.r[low];

L.r[low]=t;//将比枢轴排序码大的记录交换到高端

}

L.r[low]=L.r[0];//枢轴记录到位

returnlow;//返回枢轴记录所在位置

}//Partition

7、QSort()

算法原理:

1、对Partition()确定的两个子序列分别进行快速排序,则又可确定2个记录在序列中的最后位置,同时将序列分成4个子序列。

2、重复直至每个序列的长度均为1时,全部记录排序完毕。

流程图:

开始

Low

pivotloc=Partition(L,low,high)

QSort(L,low,pivotloc-1)

QSort(L,pivotloc+1,high)

结束

代码描述:

voidQSort(SqList&L,intlow,inthigh){//对顺序表L中的子序列r[low…high]作快速排序

if(low1

intpivotloc;

pivotloc=Partition(L,low,high);//一趟快排,将r[]一分为二

QSort(L,low,pivotloc-1);//在左子区间进行递归快排,直到长度为1

QSort(L,pivotloc+1,high);//在右子区间进行递归快排,直到长度为1

}

}

算法的时间复杂度分析:

O(nlogn)

8、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趟,得到一个按排序码从小到大排列的有序序列

流程图:

开始

i=1

i

k=i

j=i+1

j<=L.length否

L.r[j].key

k=j

k!

=i否

L.r[i]←→L.r[j]

++j

++i

结束

代码描述:

voidSelectSort(SqList&L)

{//对顺序表进行简单选择排序

RedTypex;

for(inti=1;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

算法的时间复杂度分析:

算法的改进方法(这部分可以选择):

五、测试数据和结果

1、测试数据

随机产生30000个数

2、测试结果

本程序在VC++环境下实现,下面是对以上测试数据的运行结果。

(1)主菜单显示如下:

(2)建立通信录单链表:

六、结束语

本设计完成了课题要求的任务,较熟练地运用了顺序表来解决问题,实现了顺序表的各种排序的基本算法,设计了较便捷的操作界面。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1