数据结构课程设计报告-多关键字排序的实现

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

学号:0120810340631课程设计课程名称数据结构设计题目多关键字排序的实现班级0806班姓名张军指导教师姚寒冰2010年7月2日1课程设计任务书学生姓名:张军专业班级:0806班指导教师:姚寒冰工作单位:计算机科学系题目:多关键字排序的实现初始条件:利用多关键字排序进行高考分数处理,除了需对总分进行排序外,不同的专业对单科分数的要求不同,因此在总分相同的情况下,按用户提出的单科分数的次序要求排出考生录取的次序(详见题集p169)。假设待排序的记录数不超过1000,表中记录的关键字数不超过5,各个关键字的范围均为0至100。按用户给定的进行排序的关键字的优先关系,输出排序结果。测试用例自己设计。要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)课程设计报告按学校规定格式用A4纸打印(书写),并应包含如下内容:1、问题描述简述题目要解决的问题是什么。2、设计存储结构设计、主要算法设计(用类C语言或用框图描述)、测试用例设计;3、调试报告调试过程中遇到的问题是如何解决的;对设计和编码的讨论和分析。4、经验和体会(包括对算法改进的设想)5、附源程序清单和运行结果。源程序要加注释。如果题目规定了测试数据,则运行结果要包含这些测试数据和运行输出,6、设计报告、程序不得相互抄袭和拷贝;若有雷同,则所有雷同者成绩均为0分。时间安排:1、第18周(6月28日至7月2日)完成。2、7月2日8:00到计算中心检查程序、交课程设计报告、源程序(CD盘)。指导教师签名:年月日系主任(或责任教师)签名:年月日21设计题目:多关键字排序的程序设计2问题描述:利用多关键字排序进行高考分数处理,除了需对总分进行排序外,不同的专业对单科分数的要求不同,因此在总分相同的情况下,按用户提出的单科分数的次序要求排出考生录取的次序3设计我设计的程序是有数学、英语、语文、理综4科各为0到100分。按照总分、数学、英语、语文、理综的优先顺序进行排序。由于本实验约定按LSD进行多关键字的排序。在对个关键字进行排序时采用两种策略:其一是利用稳定的内部排序法,其二是利用“分配”和“收集”的方法。所以我设计了两个程序。首先他们都是以最低位优先来排序的,由于有总分参与排序,可以不考虑理综的分数,故先按照语文分数从高到低排,再按照英语分数排,然后是数学、总分。第一个程序我用的是选择排序法,以单链表储存,因为要求是稳定的内部排续法,所以在每趟找到最大值之后将该结点插入到已排好的结点之后,以满足它是稳定的。第二个程序我参考了教材上288页的“分配”、“收集”的算法,用静态链表存储分数。在一趟排序中,将结点分配到相应的链队列中去,再按从高到低链接起来。两个程序以相同的操作界面演示。按数学、英语、语文、理综的顺序输入成绩,输入1或0确定是否还有考生。当输入0确定所有考生都已输入时,则按名次顺序输出考生的名次和分数。由于本次设计上交.exe文件,直接双击它运行完后不会停留在Pressanykeytocontinue所以输出的结果一闪而过,我在最后加了如下代码:cout输入任意字符串结束endl;3char*c;cin*c;使程序能够在这里停一下,来观察输出的结果。3.1数据结构设计稳定的内部排序法:structstudent{intrank;//名次floatmath,english,chinese,science,total;student*next;};ADTstudent{数据对象:D={ai|ai|属于student,i=1,2,......,n,n=0}数据关系:R1={ai-1,ai|ai-1,ai属于D,i=2,.....,n}基本操作:student*Creat()操作结果:用链表接收考生的各科成绩。voidInsert(student*p,student*q,student*h)初始条件:p和q为指向链表中两个节点的指针,h为指向头节点的指针。操作结果:将q指向的节点插到p指向的节点之前。voidRank(student*h)初始条件:h指向储存有各考生成绩链表的头节点。操作结果:把指针按总分、数学、英语、语文、理综的优先顺序重新排列。voidShowRank(student*h)初始条件:h指向储存有各考生成绩链表的头节点。操作结果:按名次顺序输出考生的名次和分数。}ADTstudent“分配”和“收集”的排序:#defineMAX_NUM_OF_KEY54#defineRADIX101#defineMAX_SPACE1000structSLCell{floatkeys[MAX_NUM_OF_KEY];intnext;};structSLList{SLCellr[MAX_SPACE];intkeynum;intrecnum;};ADTSLList{数据对象:D:D={a|a属于SLList}数据关系:R:数据元素同属一个集合。基本操作:P:SLListCreat()操作结果:用SLList接收考生的各科成绩。voidDistribute(SLCell*r,inti,int*f,int*e)初始条件:存在以i为下标的关键字。操作结果:以下标为i的关键字为准做一趟分配。voidCollect(SLCell*r,inti,int*f,int*e)初始条件:存在以i为下标的关键字。操作结果:以下标为i的关键字为准做一趟收集。voidRadixSort(SLList*l)操作结果:对*l中的成绩做链式基数排序。voidShowRank(SLList*l)操作结果:按名次顺序输出考生的名次和分数。}ADTSLList53.2主要算法设计稳定的内部排序法:voidRank(student*h)//把指针按总分、数学、英语、语文、理综的优先顺序重新排列{student*p,*s,*l;intr=1;for(p=h-next;p;p=s-next)//对语文成绩排序{s=p;l=p;for(;l;l=l-next)//从p所指向的节点开始向后找最高分的节点,用s指向它{if(s-chinesel-chinese)s=l;}Insert(p,s,h);}for(p=h-next;p;p=s-next)//对英语成绩排序{s=p;l=p;for(;l;l=l-next){if(s-englishl-english)s=l;}Insert(p,s,h);}for(p=h-next;p;p=s-next)//对数学成绩排序{s=p;l=p;for(;l;l=l-next){if(s-mathl-math)s=l;}Insert(p,s,h);}for(p=h-next;p;p=s-next)//对总分排序{s=p;l=p;6for(;l;l=l-next){if(s-totall-total)s=l;}Insert(p,s,h);s-rank=r++;//记录名次}}“分配”和“收集”的排序:voidDistribute(SLCell*r,inti,int*f,int*e)//以下标为i的关键字为准做一趟分配{intj,p;for(j=RADIX-1;j=0;--j)f[j]=0;//各字表初始化为空表for(p=r[0].next;p;p=r[p].next){j=r[p].keys[i];if(!f[j])f[j]=p;elser[e[j]].next=p;e[j]=p;//将下标p所指的节点插入第j个子表中}}voidCollect(SLCell*r,inti,int*f,int*e)//做一趟收集{intj,t;for(j=RADIX-1;!f[j];j--);//找第一个非空子表r[0].next=f[j];t=e[j];while(j=0){for(j--;j0&&!f[j];j--);//找下一个非空子表if(f[j]&&j=0){r[t].next=f[j];t=e[j];}//链接两个非空子表}r[t].next=0;}voidRadixSort(SLList*l)//对*l中的成绩做链式基数排序{intf[101],e[101];inti;for(i=0;i(l-recnum);i++)l-r[i].next=i+1;l-r[l-recnum].next=0;for(i=3;i0;--i){Distribute(l-r,i,f,e);Collect(l-r,i,f,e);7}}3.3测试用例设计第一个考生分数为93978788第二个考生分数为97938887第三个考生分数为86838081这样测试就会存在第一个考生和第二个考生总分相同的情况,数学分数高的排在前面。如果名次为顺序为第二个、第一个、第三个则输出为正确结果。4调试报告起初第一个程序输出结果109793888711939787881286838081这样看来排序没有排错,只是名次记录错了。可见错误在rank的值上,每次记录一次rank,r的值会自加一次。后发现在对每个关键字排完序后都记录了rank。故r的值会过大。只需要在对最后一次排序(总分的排序)后记录rank的值就行了。删掉前面几个for循环中的p-rank=r++;产生现在的程序就行了。第二个程序刚开始运行的时候输出了2个考生的信息后程序遇到问题需要关闭,调试问题指向coutrankl-r[i].keys[0]l-r[i].keys[1]l-r[i].keys[2]l-r[i].keys[3]l-r[i].keys[4]endl;显示l-r[i].keys的值为0x3345d4d8我推断i的值有问题,果然i的值是-858993460while(j=0){for(j--;j0&&!f[j];j--);if(f[j]){r[t].next=f[j];t=e[j];}}在j=0时进入while循环,for(j--;j0&&!f[j];j--);后j=-1。执行if(f[j]){r[t].next=f[j];t=e[j];},而e[]数组下标不能为-1,故产生此错误。8将其改成while(j=0){for(j--;j0&&!f[j];j--);if(f[j]&&j=0){r[t].next=f[j];t=e[j];}}后运行成功5结束语本次课程设计我做的是多关键字LSD排序,在上数据结构课时,我只是对LSD排序有了一个初步的认识,对“分配”和“收集”的方法也没有深究。在做这次实验时,我又重新翻开书本进行了一次深入的研究,LSD(最低位优先)法是从最次位关键字起进行排序,然后再对高一位的关键字进行排序,依次重复,直至对最高位关键字进行排序后便成为一个有序序列。“分配”和“收集”方法是在一趟排序中,将结点分配到相应的链队列中去,然后再链接起来。编程过程中我还用到了静态链表这个以前没有用过的数据结构,在静态链表中用整型的游标代替指针指示结点在数组中的相对位置。在做第一个程序时,我用选择排序,起初我是每进行一次选择找到最高分后把该结点的数据和已排好的结点的下一个结点数据交换。后来又想到这不是稳定的排序,才改为每趟选择找到最高分后将该结点插入到已排好的结点之后,满足稳定的要求。在实验中,我还总结了一下选择排序与“分配”和“收集”法的优缺点,在记录较少的情况下,前者是一个不错的选择,但是当记录非常多的时候,后者便体现出优势。从它们所需的辅助储存空间来看,前者很有优势,而后者需要2*RADIX个计数单元。总之,通过这次课程设计,不仅编程能力,找错能力和耐心得到的提高,我对数据结构这门课的理解也更深入了一个层次。在本实验中主要侧重的是排序的方法,考生信息很简单,主要只有分数。要使程序更完美,还可以向结构体中增加其它性息,如姓名、考号、性别等,使信息更完整。9附录F1源代码稳定的内部排序法:#includeiostreamusingnamespacestd;struct

1 / 17
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功