数据结构各种排序算法的课程设计实验报告c语言版.docx
《数据结构各种排序算法的课程设计实验报告c语言版.docx》由会员分享,可在线阅读,更多相关《数据结构各种排序算法的课程设计实验报告c语言版.docx(35页珍藏版)》请在冰豆网上搜索。
数据结构各种排序算法的课程设计实验报告c语言版
课程设计报告
课程名称:
数据结构
设计题目:
排序算法实现及比较
系别:
计算机信息工程学院
专业:
计算机科学与技术
组别:
第*组
起止日期:
12年5月1日~12年6月1日
指导教师:
***
计算机与信息工程学院二○一二年制
课程设计任务书
课程设计题目
排序算法实现将比较
组长
***
学号
20******
班级
***
系别
计算机与信息工程学院
专业
计算机科学与技术
组员
***
指导教师
***
课程设计目的
⑴加深对常见排序算法理解
⑵通过程序比较常见算法优越性
⑶熟悉加深对数据结构的了解及认识
课程设计所需环境
Windowsxp;VC++6.0
课程设计任务要求
⑴实现常见排序算法程序化
⑵测试程序比较算法优越性
⑶了解常见算法的实际应用
课程设计工作进度计划
序号
起止日期
工作内容
分工情况
1
分析实验类容
2
分工
3
算法改编成程序
4
将子程序合并及调试
数据测试及记录
5
编写报告
指导教师签字:
年月日
系(教研室)审核意见:
系(教研室)主任签字:
年月日
1.引言
伴随着社会的发展,数据也变得越来越庞大。
如何将庞大的数据进行很好的排序,使用户更加方便的查找资料,成了一件越来越重要的问题。
对于程序员来说,这将是一个挑战。
经常查找资料的朋友都会知道,面对海量的资料,如果其查找的资料没有进行排序,那么其查找资料将会是一件非常痛苦的事情。
针对这一问题,我们自此通过一个课程设计来解决它。
理论上排序算法有很多种,不过本课程设计只涉及到七种算法。
这七种算法共包括:
直接插入排序,折半插入排序,希尔排序,简单选择排序,堆排序,归并排序,冒泡排序。
本课程设计通过对这七种算法的运行情况进行对比,选择最优秀的算法来提供给用户。
希望通过我们的努力能给用户解决一些问题,带来一些方便。
2.需求分析
本课程题目是排序算法的实现,由于各方面的原因,本课程设计一共要设计七种排序算法。
这七种算法共包括:
直接插入排序,折半插入排序,希尔排序,简单选择排序,堆排序,归并排序,冒泡排序。
七种排序各有独到之处,因此我们要通过各种调试分析来比较其优劣长短。
为了小组分工的方便,我们特意把子函数写成HeaderFile文件。
这样操作不仅可以使小组分工更加简洁明了,还可以方便子函数的调用,更可以使写主函数时一目了然。
为了运行时的方便,我们将七种排序方法进行编号,其中1为直接插入排序,2为折半插入排序,3为希尔排序,4为简单选择排序,5为堆排序,6为归并排序,7为冒泡排序。
通过这七种选项,可以让用户简单明了的去选择使用哪一种排序方法。
本课程就是通过对5组占用内存大小不同的数据调试来测试这七种算法运行的时间长短,从中选择面对不同大小的文件时,哪一种算法更为快捷。
软件环境本课程设计所用操作系统为Windows-XP操作系统,所使用的软件为MicrosoftVisualC++6.0;
3.详细设计
3.1直接插入排序
⑴算法思想:
直接插入排序是一种最简单的排序方法,它的基本操作是将一个记录插入到一个已排好序的有序表中,从而得到一个新的、记录数增一的有序表。
在自i-1起往前搜索的过程中,可以同时后移记录。
整个排序过程为进行n-1趟插入,即:
先将序列中的第一个记录看成是一个有序的子序列,然后从第二个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。
⑵程序实现及核心代码的注释:
for(i=1;ifor(j=0;j
if(r.base[i]{
temp=r.base[i];//保存待插入记录
for(i=i;i>j;--i)
r.base[i]=r.base[i-1];//记录后移
r.base[j]=temp;//插入到正确的为位置
}
r.base[r.length]='\0';
3.2折半排序
⑴算法思想:
由于折半插入排序的基本操作是在一个有序表中进行查找和插入,这个“查找”操作可利用折半查找来实现,由此进行的插入排序称之为折半插入排序。
折半插入排序所需附加存储空间和直接插入排序相同,从时间上比较,这般插入排序仅减少了关键字间的比较次数,而记录的移动次数不变。
因此,这般插入排序的时间复杂度仍为O(n2)。
⑵程序实现及核心代码的注释:
voidzb(FILE*fp)
{//对顺序表作折半插入排序
for(i=1;i{
temp=r.base[i];//将r.base[i]寄存在temp中
low=0;
high=i-1;
while(low<=high)//在base[low]到key[high]中折
半查找有序插入的位置
{
m=(low+high)/2;//折半
if(temphigh=m-1;//插入低半区
else
low=m+1;//插入高半区
}
for(j=i-1;j>=high+1;--j)
r.base[j+1]=r.base[j];//记录后移
r.base[high+1]=temp;//插入
}
3.3希尔排序
⑴算法思想:
先将整个待排记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
其中,子序列的构成不是简单的“逐段分割”,而是将分隔某个“增量”的记录组成一个子序列。
⑵程序实现及核心代码的注释:
for(k=0;k<10;k++)
{
m=10-k;
for(i=m;iif(r.base[i]{
temp=r.base[i];//保存待插记录
for(j=i-m;j>=0&&tempr.base[j+m]=r.base[j];//记录后移,查找插入位置
r.base[j+m]=temp;//插入
}
}
3.4简单选择排序
⑴算法思想:
在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
⑵程序实现及核心代码的注释:
for(i=0;i{//i为排好序的数的下标,依次往后存放排//好序的数
temp=r.base[i];//将待放入排好序的数的下标的数保存
for(j=i,m=j+1;mif(r.base[j]>r.base[m])
j=m;
r.base[i]=r.base[j];//把下标为j的数与i数互换;
r.base[j]=temp;
}
3.5堆排序
⑴算法思想:
堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。
将序列所存储的元素A[N]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:
树中任一非叶结点的元素均不大于(或不小于)其左右孩子(若存在)结点的元素。
算法的平均时间复杂度为O(NlogN)。
⑵程序实现及核心代码的注释:
voiddp(FILE*fp)
{
for(i=r.length/2;i>=1;--i)//把r.base[1...r.length]建成大顶堆
HeapAdjust(r.base,i,r.length);
for(i=r.length;i>=2;--i)
{
temp=r.base[1];
r.base[1]=r.base[i];
r.base[i]=temp;
HeapAdjust(r.base,1,i-1);//将r.base[1...i-1]重新调整为大顶堆
}
voidHeapAdjust(char*r,intk,intm)
{
i=k;x=r[i];j=2*i;//沿key较大的孩子节点向下筛选
while(j<=m)//j为key较大的记录的下标
{
if((jr[j+1]))
j++;
if(x>r[j])
{//插入字符比当前的大,交换
r[i]=r[j];
i=j;
j*=2;
}
else//否则比较停止。
j=m+1;
}
r[i]=x;//把字符x插入到该位置,元素插入实现
}
3.6归并排序
1算法思想:
先将相邻的个数为1的每两组数据进行排序合并;然后对上次归并所得到的大小为2的组进行相邻归并;如此反复,直到最后并成一组,即排好序的一组数据。
⑵程序实现及核心代码的注释:
voidmerge(SqList6r,inth,intm,intw,SqList6t)
{//对相邻两组数据进行组合排序;
inti,j,k;
i=h;
j=m+1;//j为合并的第二组元素的第一个数位置
k=h-1;//k为存入t中的数的位置;
while((i<=m)&&(j<=w))
{//依次排列两组数据
k++;
if(r.base[i]<=r.base[j])//将第一组数据与第二组数据分别比较;
t.base[k]=r.base[i++];
else
t.base[k]=r.base[j++];
}
if(i>m)//第一组数据先排完的情况
while(j<=w)t.base[++k]=r.base[j++];
else
while(i<=m)t.base[++k]=r.base[i++];
}
voidtgb(ints,intn,SqList6r,SqList6t)
{//对数据进行每组s个数的归并排序;
inti=1;//i为要合并两组元素的第一个数位置;
while(i<=(n-2*s+1))
{
merge(r,i,i+s-1,i+2*s-1,t);//i+s-1为要合并的第一组元素的最后一
//数位置、i+2*s-1为要合并的两组元素
//最后一个数位置;
i=i+2*s;
}
if(i<(n-s+1))//考虑n不能被s整除,如果余下的数少于
//2*s但大于s,也就是余下的数不能凑成
//两组,凑一组有余,则把余下的数进行组
/