数据结构各种排序算法的课程设计实验报告C语言版优秀.docx
- 文档编号:28581984
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:39
- 大小:901.38KB
数据结构各种排序算法的课程设计实验报告C语言版优秀.docx
《数据结构各种排序算法的课程设计实验报告C语言版优秀.docx》由会员分享,可在线阅读,更多相关《数据结构各种排序算法的课程设计实验报告C语言版优秀.docx(39页珍藏版)》请在冰豆网上搜索。
数据结构各种排序算法的课程设计实验报告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;i for(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(temp high=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;i if(r.base[i] { temp=r.base[i];//保存待插记录 for(j=i-m;j>=0&&temp r.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;m if(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((j 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,也就是余下的数不能凑成 //两组,凑一组有余,则把余下的数进行组 //合,并对其进行排序; merge(r,i,i+s-1,n,t); else//如果余下的数少于s,则余下的数进行组//合,并进行排序; while(i<=n) t.base[i]=r.base[i++]; } voidgb(FILE*fp)//归并主函数; { n=r.length; SqList6t; t.base=(char*)malloc(r.stacksize*sizeof(char)); //给待排序的数组t申请内存; while(s { tgb(s,n,r,t);//s为每组元素的个数、n为元素总个数、r //为原数组,t为待排序的数组,进行归并排 s*=2;//序;把元素个数相同的两组合并并进行重新 //定义成新的一组,此组元素个数为2*s; if(s //当元素个数小于n时,对其进行合并排序; else//当元素个数大于n时,对剩下的数排序; { i=0; while(i<=n) { r.base[i]=t.base[i+1]; i++; } } } } 3.7冒泡排序 ⑴算法思想: 1、先将一组未排序的数组的最后一个数与倒数第二个数进行比较,并将较小的数放于两个数中较前的位置,然后将比较后的较小的数与倒数第三个进行比较,依次比较到第一个数,即可得到第一个数是所有数中最小的数;2、然后再将数组的最后一个数与倒数第二个数进行比较,并将较小的数放于两个数中较前的位置,依次比较到第二个数,3、如此循环到只剩最后两个比较,即得到排好序的一组数。 ⑵程序实现及核心代码的注释: for(i=0;i { for(j=r.length-2;j>=i;j--)//从后往前依次两两比较,较小的被调换到前面; if(r.base[j+1] { temp=r.base[j+1];//将后面的较小的数保存起来; r.base[j+1]=r.base[j];//将前面的较大的数放在后面较小的数的位置; r.base[j]=temp;//将较小的数放在前面的较大的数的位置; } } 4.调试 检测主函数是否能够稳定运行(如图4-1): 图4-1 5.调试及检验 5.1直接插入排序 输入字符并保存(如图5-1.1): 调用算法【1】处理文件(如图5-1.2): 处理结果(如图5-1.3): 图5-1.1图5-1.2 图5-1.3 5.2折半插入排序 输入字符并保存(如图5-2.1): 调用算法【2】处理文件(如图5-2.2): 处理结果(如图5-2.3): 图5-2.1图5-2.2 图5-2.3 5.3希尔排序 输入字符并保存(如图5-3.1): 调用算法【3】处理文件(如图5-3.2): 处理结果(如图5-3.3): 图5-3.1图5-3.2 图5-3.3 5.4简单选择排序 输入字符并保存(如图5-4.1): 调用算法【4】处理文件(如图5-4.2): 处理结果(如图5-4.3): 图5-4.1图5-4.2 图5-4.3 5.5堆排序 输入字符并保存(如图5-5.1): 调用算法【5】处理文件(如图5-5.2): 处理结果(如图5-5.3): 图5-5.1图5-5.2 图5-5.3 5.6归并排序 输入字符并保存(如图5-6.1): 调用算法【6】处理文件(如图5-6.2): 处理结果(如图5-6.3): 图5-6.1图5-6.2 图5-6.3 5.7冒泡排序 输入字符并保存(如图5-7.1): 调用算法【7】处理文件(如图5-7.2): 处理结果(如图5-7.3): 图5-7.1图5-7.2 图5-7.3 6.测试与比较 6.1调试步骤 ⑴在kcsj文本文件中随机输入一串字符串,然后保存下来并且复制备份在桌面上。 运行程序,调用不算法去处理文件。 用秒表计算从开始到结束所用的时间,并记录下来。 ⑵将文件夹中的kcsj文本文件删除,将桌面上的备份文件考入文件夹来代替原文件,以保障被操作数据的一致性。 ⑶用同样的方法依次测试七种算法所用的时间,并记录下来。 ⑷再将数据依次改变为占用内存大小为50KB、100KB、200KB、512KB、1024KB的数字串,重复以上的操作。 ⑸将记录的数据(如表6-1)。 表6-1同一文件不同算法处理的时间表 直接插入排序 折半插入排序 希尔排序 简单选择排序 堆排序 归并排序 冒泡排序 50KB >1m 1.5s 0.2s 6.0s <0.1s <0.1s 6.1s 100KB >3m 5.5s 1.1s 23s <0.1s <0.1s 24s 200KB -- 20s 3.8s -- <0.1s <0.1s >1m 512KB -- >1m 14s -- <0.1s 0.1s >3m 1024KB -- >3m >1m -- 0.2s 0.3s >10m --: 表示时间过长 6.2结论 通过实验结果的比较与分析我们发现: 直接插入排序、冒泡排序、简单选择排序及折半插入排序是低效率的排序方式;所以我们实际编程重要尽可能的避免他们的出现;我们应该用较先进的归并排序及堆排序。 7.实验心得与分析 通过本次课程设计,我们小组的每个成员都学到了很多东西。 首先要说的是我们的编程能力,在这一次的课程设计中我们的编程能力均得到了一定程度的提升。 并且通过这次课程设计,我们更加熟悉了如何使用HeaderFile文件。 本次课程设计,让我们对于直接插入排序,折半插入排序,希尔排序,简单选择排序,堆排序,归并排序,冒泡排序等七种排序算法的思想有了进一步的认识,同时对七种算法的应用有了更进一步的掌握。 通过这次课程设计,我们对于解决实际问题的能力有了进一步提高。 最重要的是,这次课程设计大大的训练了我们的小组团队协作能力。 通过这次课程设计我们小组各成员的团队协作能力都有了很大的提升。 这种团队协作能力对于我们学编程的来说是极其重要的,同时也是必不可少的。 当然,我们写程序的时候遇到了很多困难。 而且在程序调试过程中出现了很多错误与警告,不过在队员及老师的帮助下均得到了解决。 当程序可以运行后,程序的运行过程中同样也也出现了很多错误,甚至出现了不兼容的情况。 不过,后来在队员及老师的帮助下也均得到了解决。 然而,我们的程序还有一点瑕疵让我们感到美中不足。 那就是在归并算法运行过程中,当输入为9个字符时,排序结果会出现偶然误差。 经过分析,我们认为这点是系统的问题。 不过,这仍然是一点让我们感到遗憾的地方。 8.附录 8.1直接插入排序 #include #include #defineQ1000 typedefstruct{ char*base; intstacksize; intlength; }SqList1; voidzj(FILE*fp) { SqList1r; inti,j; chartemp,*p; r.base=(char*)malloc(Q*sizeof(char)); r.stacksize=Q; r.length=0; while(! feof(fp)) { fscanf(fp,"%c",r.base); r.base++; r.length++; if(r.length==r.stacksize) { r.base=r.base-r.length; r.base=(char*)realloc(r.base,(r.stacksize+Q)*sizeof(char)); if(! r.base) { printf("ERROR"); return; } r.base=r.base+r.stacksize; r.stacksize+=Q; } } r.length--; r.base--; r.base=r.base-r.length; for(i=1;i for(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'; rewind(fp); fprintf(fp,"%s",r.base); fclose(fp); free(r.base); } 8.2折半插入排序 #include #include #defineQ1000 typedefstruct{ char*base; intstacksize; intlength; }SqList2; voidzb(FILE*fp) { SqList2r; inti,j,m,low,high; chartemp; r.base=(char*)malloc(1000*sizeof(char)); r.stacksize=1000; r.length=0; while(! feof(fp)) { fscanf(fp,"%c",r.base); r.base++; r.length++; if(r.length==r.stacksize) { r.base=r.base-r.length; r.base=(char*)realloc(r.base,(r.stacksize+Q)*sizeof(char)); if(! r.base) { printf("ERROR"); return; } r.base=r.base+r.stacksize; r.stacksize+=Q; } } r.length--; r.base--; r.base=r.base-r.length; for(i=1;i { temp=r.base[i]; low=0; high=i-1; while(low<=high) { m=(low+high)/2; if(temp
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 各种 排序 算法 课程设计 实验 报告 语言版 优秀