数据结构课程设计多关键字排序.docx

上传人:b****6 文档编号:5858276 上传时间:2023-01-01 格式:DOCX 页数:30 大小:306.11KB
下载 相关 举报
数据结构课程设计多关键字排序.docx_第1页
第1页 / 共30页
数据结构课程设计多关键字排序.docx_第2页
第2页 / 共30页
数据结构课程设计多关键字排序.docx_第3页
第3页 / 共30页
数据结构课程设计多关键字排序.docx_第4页
第4页 / 共30页
数据结构课程设计多关键字排序.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

数据结构课程设计多关键字排序.docx

《数据结构课程设计多关键字排序.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计多关键字排序.docx(30页珍藏版)》请在冰豆网上搜索。

数据结构课程设计多关键字排序.docx

数据结构课程设计多关键字排序

工学院计算机工程学院

课程设计报告

设计名称:

数据结构课程设计

选题名称:

多关键字排序

姓名:

学号:

专业班级:

网络工程081

系(院):

计算机工程学院

设计时间:

设计地点:

软件工程实验室、教室

成绩:

指导教师评语:

签名:

1.课程设计目的

3.训练学生灵活应用所学数据结构知识,独立完成问题分析,结合数据结构理论知识,编写程序求解指定问题。

4.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;

5.提高综合运用所学的理论知识和方法独立分析和解决问题的能力;

6.训练用系统的观点和软件开发一般规范进行软件开发,巩固、深化学生的理论知识,提高编程水平,并在此过程中培养他们严谨的科学态度和良好的工作作风。

2.课程设计任务与要求:

任务

题目:

多关键字的排序

【问题描述】

多关键字的排序有其一定的实用范围。

例如:

在进行高考分数处理时,除了需对总分进行排序外,不同的专业对单科分数的要求不同,因此尚需在总分相同的情况下,按用户提出的单科分数的次序要求排出考生录取的次序。

【基本要求】

(1)假设待排序的记录不超过10000,表中记录的关键字数不超过5,各个学科关键字的范围均为0至100,总分关键字的范围是0-300。

按用户给定的进行排序的关键字的优先关系,输出排序结果。

(2)约定按LSD法进行多关键字的排序。

在对各个关键字进行排序时采用两种策略:

其一是利用稳定的内部排序法,其二是利用“分配”和“收集”的方法。

并综合比较这两种策略。

【测试数据】

由随机数产生器生成。

【实现提示】

由于是按LSD方法进行排序,则对每个关键字均可进行整个序列的排序,但在利用通常的内部排序

方法进行排序时,必须选用稳定的排序方法

要求:

1、在处理每个题目时,要求从分析题目的需求入手,按设计抽象数据类型、构思算法、通过设计实现抽象数据类型、编制上机程序和上机调试等若干步骤完成题目,最终写出完整的分析报告。

前期准备工作完备与否直接影响到后序上机调试工作的效率。

在程序设计阶段应尽量利用已有的标准函数,加大代码的重用率。

2、.设计的题目要求达到一定工作量(300行以上代码),并具有一定的深度和难度。

3、程序设计语言推荐使用C/C++,程序书写规范,源程序需加必要的注释;

4、每位同学需提交可独立运行的程序;

5、每位同学需独立提交设计报告书(每人一份),要求编排格式统一、规范、内容充实,不少于

10页(代码不算);

6、课程设计实践作为培养学生动手能力的一种手段,单独考核。

3.课程设计说明书

一需求分析1)选题功能分析

【题目的意义】

1、对高考分数按照总分和不同学科的分数按照优先级顺序排出考生录取的次序,以满足不同专业对单科分数的要求。

2、对不同排序策略进行综合比较。

【实现的功能】

1、用C语言设计实现一个高考成绩排序系统。

2、创建模拟的高考考生成绩表,存放到txt文档中。

考生考号为1,2,3…用伪随机数生成器生成各考号学生的各个学科成绩,并计算总分成绩。

3、由于实际中高考考生成绩表是已知的(模拟创建的txt文档),程序能从文件中读取数据。

从创建的考生成绩表中读取数据,并对数据处理

4、按照学科的优先级顺序,对学生的成绩排序。

既可以以某一学科的单科成绩优先级最高排序,也可以先按总分优先级最高来排序。

5、在对各个关键字即单科成绩进行排序的时候,分别用稳定的内部排序法(冒泡法)以及“’分配’和’搜集’”的方法进行排序。

6、能够对冒泡法排序策略和“’分配’和’搜集’”方法排序策略进行的执行时间进行比较。

7、输入数据:

1各科英文首字母的代号,字符型,如smce

2整型数,0-10000

1输出程序用两种方法进行排序的进程和执行时间

2输出前n名学生的信息

二概要设计

1、伪随机生成的数据包含语文、数学、英语三科成绩。

总成绩为语文、数学、英语三科成绩的

和。

学号按成绩数组的下标赋值,生成学生成绩记录,将该记录保存到txt文档中

2、从上面的txt文档中读取数据到一个二维数组中,以便对学生信息进行处理

3、给出排序的优先关系,根据优先关系由低位向高位逐个关键字进行排序。

4、对单科成绩进行排序的时候,单科成绩虽然是0-100,但总成绩是0-300,所以要建301个队

列进行排序,先按“分配”和“搜集”的方法进行一趟“基数排序”;然后再按照稳定的内

部排序法(冒泡法)进行排序。

将搜集好的或排序好的序列存储,以进行对次优先级的关键

字进行再排序。

5、将排序好的学生成绩按照用户提出的提取人数的要求,保存到另一个txt文档中,并输出到

屏幕

6、系统用到的抽象数据类型定义

doubleBubTime1,//按第一个关键字代表的学科成绩用冒泡法排序执行的时间

BubTime2,

BubTime3,

BubTime4,BubTimeSum,//冒泡法排序的总时间

DCTime1,//按第一个关键字代表的学科成绩用分配和收集的方法执

行的时间

DCTime2,

DCTime3,DCTime4.

DCTimeSum;〃分配和收集法排序的总时间

intscore[10000][5],//随机创建的模拟学生记录源数组

bubble[10000][5],〃进行冒泡法排序时用来存放学生记录源数组,并且随排序

进行数组中的记录发生交换

copy[10000][5];〃从模拟的学生记录源txt文件中读取学生记录到该数组

structLSDd[301];〃分配数组,该处考虑到把总分(0-300)也列入优先级序列

中,因此建立了301个队列

int*c[10000];〃用来存放收集到的学生记录

charx[5];〃存放有优先关系的学科代号序列

7、系统中的各个函数模块

1:

voidCreatScore(intscore[10000][5]);

高考中该表是已知的,不必创建

2:

voidCollect(structLSDd[301],int*c[10000]);

分配好的记录收集到c指针数组保存

3:

voidInitDivide(structLSDd[301]);

次收集后必须做的工作

4:

doubleDCSort(structLSDd[301],int*c[10000],intn);排序的方法

5:

doubleBubbleSort(intscore[10000][5],intn);

6:

voidPrint();

出到屏幕上

7:

voidsavesources(intscore[10000][5],intn);

存放到文件中

8:

voidsaveresults(intscore[10000][5],intn);

学生记录),将这n条学生的记录存放到新的文件中

9:

voidload(intscore[10000][5]);

取记录到该二维数组中

&各函数之间的调用关系

〃随机创建学生记录表score。

正常

//LSD法排序中的收集函数,即将

〃用于初始化临时分配数组,在每

〃分配(Divide)和收集(Collect)

〃冒泡法排序

〃将排序结果文件中的记录数据输

〃将模拟创建的高考学生信息记录

//按照用户的要求(总成绩在前多少名的

//从学生高考记录源文件中读

1:

主函数可以调用除子函数2之外的所有函数

2:

子函数4可以调用子函数2和3

【功能模块图】

 

 

三详细设计

1.抽象数据类型:

该数据类型是在分配和收集的时候存放分配成绩数组

1'抽象数据类型structLSD

structLSD//队列的结构类型,链表存储结构类型

{

int*cur;〃当前位置

structLSD*next;//队列中下一个位置

};

,随机生成语

2'CreatScore(intscore]RecordNumber][KeyNumber])函数

/*创建一个含有RecordNumber名学生成绩记录的score,包含语文、数学、英语、总分和学号文、数学、英语的成绩。

*传递的参数是成绩数组score,无返回值

*/

voidCreatScore(intscore[RecordNumber][KeyNumber])

{

/*伪随机生成语文、数学、英语的成绩*/

for(i=0;i

{for(j=0;j<3;j++)

{score[i][j]=rand()%101;//成绩的范围是0-100

}

}

/*总分成绩初始化*/

for(i=0;i

{

score[i][3]=score[i][0]+score[i][1]+score[i][2];

}

/*学号的初始化*/

for(i=0;i

//总成绩为各科成绩之和

//学号是按从前到后的顺序依次赋值的

score[i][4]=i+1;

 

3'收集函数Collect(structLSDd[QueueNumber],int*c[RecordNumber])/*将分配好的成绩数组d,收集到c指针数组保存*传递的参数为分配好的数组d和收集的指针数组

*/

void

{

C,无返回值

structLSD*p;for(i=QueueNumber-1;i>=0;i--){

if(d[i].cur!

=NULL)

{

〃当前队列不空,即有学生的成绩分配到该队列

 

p=&d[i];while(p->cur!

=NULL){

//当前位置有学生的成绩

c[j]=P_>cur;j++;p=p->next;

//收集到C指针数组中

//指针p指向该队列的下一个位置

 

4初始化分配数组InitDivide(structLSDd[QueueNumber])

 

〃学生的成绩就是队列号

//当前队列为空

〃将c[j]代表的学生的成绩添加到该队列中

//初始化刚刚添加了学生记录的队列

//当前队列不为空

〃将c[j]代表的学生的成绩添加到该队列中

//新申请一个空间来存放学生成绩

//分配完毕

〃将分配好的成绩序列收集到c中

//初始化分配数组

II返回执行时间

/*初始化d数组即置空,在每一次收集后必须做的工作

*传递的参数是structLSDd[QueueNumber],无返回值*/voidInitDivide(structLSDd[QueueNumber])

{

for(inti=O;i

{

d[i].cur=NULL;

d[i].next=NULL;

}

}

5'"分配"和"收集"方法排序doubleDCSort(structLSDd[QueueNumber],int

*c[RecordNumber],intn)

/*"分配"和"收集"方法排序

*分配数组为d,收集数组为c

*进行排序的关键字所代表的学科成绩n在分配数组中的位置就是n

*传递的参数是分配数组structLSDd[QueueNumber],用来收集的指针数组int*c[RecordNumber],关键

字代表的学科在数组中的下标

*/

doubleDCSort(structLSDd[QueueNumber],int*c[RecordNumber],intn){

/*按关键字代表的学科成绩将成绩分配到d中*/

for(j=0;j

{

temp=c[j][n];

if(d[temp].cur==NULL)

{

d[temp].cur=c[j];

p=&d[temp];

p仁(structLSD*)malloc(LENGTH);p1->cur=NULL;

p1->next=NULL;

p_>next=p1;

}

else

{

p=&d[temp];

/*循环,一直到队列的结尾*/

while(p->cur!

=NULL)p=p->next;

p->cur=c[j];

p仁(structLSD*)malloc(LENGTH);p1->cur=NULL;

p1->next=NULL;

p_>next=p1;

}

}

Collect(d,c);

InitDivide(d);

returntime;

}

6'冒泡法排序doubleBubbleSort(intbubble[R

/*冒泡法排序

*传递的参数是学生成绩记录intbubble[RecordNumber][KeyNumber],关键字所代表学科成绩在数组中的

下标

*/

doubleBubbleSort(intbubble[RecordNumber][KeyNumber],intn)

{

for(inti=0;i

{

for(intj=0;j

{

if(bubble[j][n]

{

/*交换学生的各科成绩*/

for(intm=0;m

{

temp=bubble[j][m];

bubble[j][m]=bubble[j+1][m];bubble[j+1][m]=temp;

}

}

}

}

returntime;//返回排序执行的时间

}返回执行的时间

}

7'Print()函数

/*从排序结果存放的文件recordresults.txt中读取记录输出到屏幕上

*/

voidPrint()

{

FILE*fp;

if((fp=fopen("D:

\\recordresults.txt","rb"))==NULL)

printf("文件打开失败!

\n");

else

printf("文件打开成功!

\n");

chart;

while(fscanf(fp,"%c",&t)&&!

feof(fp))

{

if(t!

=EOF)

printf("%c",t);

}//如果读到结束符,循环结束,输出结束

fclose(fp);//关闭文件

}

8'savesources(intscore[RecordNumber][KeyNumber],intn)

/*保存学生记录的函数

*参数为要保存的学生记录和记录条数

*无返回值

*/

voidsavesources(intscore[RecordNumber][KeyNumber],intn)

{

if((fp=fopen("D:

\\recordsources.txt","wb"))==NULL)//只写

{

printf("文件打开失败!

\n");exit

(1);

}

fprintf(fp,"%d",n);//将记录条数写入文件

fprintf(fp,"\r\n");〃将换行符号写入文件

for(i=0;i

{

fprintf(fp,%10d%-10d%-10d%-10d%-10d",score[i][4],score[i][0],score[i][1],score[i][2],score[i][3]);〃格式写入记录

fprintf(fp,"\r\n");〃将换行符号写入文件

}

fclose(fp);

}

9saveresults(intscOReCordNumber][KeyNumber],intn)

/*保存学生记录的函数

*参数为要保存的学生记录和记录条数

*无返回值

*/

//指向文件的指针

//只写,打开或建立一个二进制文件,只允许

〃将记录条数写入文件

〃将换行符号写入文件

voidsaveresults(intscore[RecordNumber][KeyNumber],intn){

FILE*fp;

if((fp=fopen("D:

\\recordresults.txt","wb"))==NULL)

写数据

{

printf("文件打开失败!

\n");exit

(1);

}

fprintf(fp,"%d",n);

fprintf(fp,"\r\n");

for(i=0;i

{

fprintf(fp,%10d%-10d%-10d%-10d%-10d",score[i][4],score[i][0],score[i][1],score[i][2],score[i][3]);〃格式写入记录

fprintf(fp,"\r\n");〃将换行符号写入文件

}

fclose(fp);

}

10'load(intscoRfcordNumber][KeyNumber])

/*读入函数,把文件中的记录度入到二维数组中

*参数为结构体数组

*/

voidload(intscore[RecordNumber][KeyNumber])

{

FILE*fp;

if((fp=fopen("D:

\\recordsources.txt","rt"))==NULL)//打开文件

printf(”文件打开失败!

\n");exit

(1);

〃读入记录数

〃按格式读入记录

}fscanf(fp,"%d",&n);for(i=0;i

}

11'算法分析

1)LSD算法:

这是一种“低位优先”的排序方法,借助一趟基数排序的方法,先按最低位的值对记录进行初步排序,在此基础上再按次低位的值进行进一步排序。

以此类推,有低位到高位,每一趟都是在前一趟的基础上,根据关键字的某一位对所有的记录进行排序,直至最高位,这样就完成了基数排序的全过程。

从算法中可以看出,对于n个记录(每个记录含d个子关键字,每个子关键字的取值范围为RADIX个值)进行链式排序的时间复杂度为0(d(n+RADIX)),其中每一趟分配算法的时间复杂度为0(n),每一趟收集的算法的时间复杂度为O(RADIX),整个排序进行d趟分配和收集,所需辅助空间为2*RADIX个队列指针。

由于需要链表作为存储结构,则相对于其他以顺序结构存储记录的排序方法而言,还增加了n个指针域的空间。

2)冒泡法排序:

该排序是比较简单的交换类排序方法,通过相邻数据元素的交换,逐步将带排序列变成有序序列的过程。

最坏情况下,待排序的记录按关键字的逆序进行排列,此时,每一趟冒泡排序需要进行i次比较,3i次移动。

经过n-1趟冒泡排序后,总的比较次数为N=Ei=n(n-1)/2,n=1,2,…,n-1.总的移动次数为3n(n-1)/2次,因此该算法的时间复杂度为O(n*n),空间复杂度为O

(1)。

另外,冒泡排序法是一种稳定的每部排序法。

四测试成果

崖序正在模拟创建16000^高考成绩记录并保存到文件D:

XFecordresDUPces.txt中、麟畐曦保存成功¥_

您可以】昂过路栓D:

\i*ecordsources.txt逬行查看.:

.

E序系统开始运行*******

10000条记录到排序系统中

富弩賈要按嗚嬲业舉醪專绩逬行排序’比如(总分,数学,悟文,英语)

鵜赛曙駅蹩行林比如廊数学’语文’英涪)

耀夢配请稍后…

本義分配知收集用时:

0.AAAs

冒追法遼行排序,请稍后…

本次冒泡连徘序用时;1-344s

请稍后…

S

列在程序正在按s代表的学程a行唸分配,请稍后…夯配完电下面开始进行收矍葡霏…

收峯完取

本次分配和收集用时:

0-000s

黯寵麟㈱購翻间九0-032

请问您要提取多少条学生的成绩信息(0-10000):

20

郴翳少条学E信息g)=20

2B

2803

100

?

?

98

29?

6575

?

a

98

98

294

611

?

?

?

?

94

29Q

2146

75

?

2

100

287

4474

98

89

286

97

97

91

285

3323

8S

9?

283

1030

87

98

98

283

佔砖

92

100

89

281

4711

9丄

97

92

281

翦62

9G

94

91

281

677

90

92

99

291

1090

95

8&

100

281

4463

99

84

98

291

L943

G7

%

99

2QQ

4998

?

4

1R9

279

4825

9S

?

2

39

279

3345

9S

8?

94

2?

9

5923

94

98

279

7755

?

9

99

2?

6

Press

anykeyto

inue

五附录(源程序清单)

#include

#include

#include

#include

#defineLENGTHsizeof(structLSD)

intmain()

doubleBubTimel,

BubTime2,

BubTime3,

BubTime4,BubTimeSum,DCTimel,DCTime2,DCTime3,DCTime4,DCTimeSum;

//按第一个关键字代表的学科成绩用冒泡法排序执行的时间

//冒泡法排序的总时间

//按第一个关键字代表的学科成绩用分配和收集的方法执行的时间

//分配和收集法排序的总时间

intscore[10000][5],〃随机创建的模拟学生记录源数组bubble[10000][5],

发生交换

//进行冒泡法排序时用来存放学生记录源数组,

并且随排序进行数组中的记录

copy[10000][5];structLSDd[301];301个队列int*c[10000];charx[5];

//从模拟的学生记录源txt文件中读取学生记录到该数组

//分配数组,该处考虑到把总分(0-300)也列入优先级序列中,因此建立了

//用来存放收集到的学生记录

//存放有优先关系的学科代号序列

/*初始化c,使其与score函数"同步"*/for(inti=0;i<10000;i++)

c[i]=score[i];

InitDivide(d);

//初始化队列

/*在实际中全部学生的高考

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

当前位置:首页 > 经管营销

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

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