当前位置:文档之家› 数据结构课程设计 多关键字排序 高考排序

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

淮海工学院计算机工程学院
课程设计报告
设计名称:数据结构课程设计
选题名称:多关键字排序
姓名:周宣学号:110821120 专业班级:网络工程081
系(院):计算机工程学院
设计时间:2009.12.28~2010.1.12
设计地点:软件工程实验室、教室
{
printf("文件打开失败!\n");
exit(1);
}
fscanf(fp,"%d",&n); //读入记录数
for(i=0;i<n;i++)
fscanf(fp,"%d %d %d %d %d",
&score[i][4],
&score[i][0],
&score[i][1],
&score[i][2],
&score[i][3]); //按格式读入记录fclose(fp);
}
11’算法分析
1)L SD算法:
这是一种“低位优先”的排序方法,借助一趟基数排序的方法,先按最低位的值对记录进行初步排序,在此基础上再按次低位的值进行进一步排序。

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

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

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

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

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

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

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

四测试成果
五附录(源程序清单)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
struct LSD //抽象类型定义,队列的结构类型,由于是按LSD法进行的排序,所以命名为LSD
{
int *cur; //当前位置
struct LSD *next;
};
#define LENGTH sizeof(struct LSD)
void CreatScore(int score[10000][5]); //随机创建学生记录表score。

正常高考中该表是已知的,不必创建
void savesources(int score[10000][5],int n); //将模拟创建的高考学生信息记录存放到文件中
void load(int score[10000][5]); //从学生高考记录源文件中读取记录到该二维数组中
void Collect(struct LSD d[301],int *c[10000]); //LSD法排序中的收集函数,即将分配好的记录收集到c指针数组保存
void InitDivide(struct LSD d[301]); //用于初始化临时分配数组,在每一次收集后必须做的工作
double DCSort(struct LSD d[301],int *c[10000],int n); //分配(Divide)和收集(Collect)排序的方法double BubbleSort(int score[10000][5],int n); //冒泡法排序
void saveresults(int score[10000][5],int n); //按照用户的要求(总成绩在前多少名的学生记录),将这n条学生的记录存放到新的文件中
void Print(); //将排序结果文件中的记录数据输出到屏幕上
int main()
else
printf("文件打开成功!\n");
char t;
while(fscanf(fp,"%c",&t)&&!feof(fp))
{
if(t!=EOF)
printf("%c",t);
} //如果读到结束符,循环结束,输出结束
fclose(fp); //关闭文件
}
六用户手册
本程序的运行环境为DOS系统,执行文件为“LSDSort.exe”
进入程序后的界面如下:
用户此时可以按路径D:\\recordresources.txt文档中查看模拟高考成绩表自动计算出分配收集法和冒泡法分别所需要的时间,综合比较两种方法
按照提示输入自己要求的各个成绩的优先关系序列,然后程序自动进入排序系统,最后程序就将分配和收集的过程以及冒泡法排序的过程分别输出,最后得到排序结果。

然后会到下面的界面:
即提示用户输入录取的学生数目,由于把全部成绩输出对于高校录取并没有用,所以只要按一定的人数提取记录就可以了
4.课程设计心得
这次课程设计收获很大,从一开始的迷迷糊糊不明白题意,到现在很清楚该设计的各个方面,我在无数次的调试过程中学到了很多有用的东西
1、模块化的思想。

使程序模块化之后,可以很方便的调用和对某个模块的修改,我由于一开始对题目的要求不到位,在最后验收的时候发现一些功能未实现的问题,如果我的程序很乱,函数之间没有清晰的调用关系,参数传递混乱的话,我就很难修改它,但是我用了模块化的思想,在很短的时间之内就将程序添加了文件流操作的功能,使程序更加满足实际要求,也更加清晰。

现在可以很容易添加一个不同的功能模块。

2、调试技巧。

在调试过程中同学们遇到了很多不同的错误,比如:错误提示如下
Cpp1.obj : error LNK2001: unresolved external symbol "void __cdecl CreatScore(int (* const)[5])" (?CreatScore@@YAXQAY04H@Z)
Debug/Cpp1.exe : fatal error LNK1120: 1 unresolved externals。

根据以前的经验知道这是连接上出了错,而且以前遇到类似的错误是因为传递的参数不同而导致的,现在也想到估计是同样的问题,但是看程序,参数传递正常。

后来在找CreatScore时发现我不知道什么时候把它剪切了,这就好像是声明了程序要用CreatScore,而且也用了,但是并没有说明CreatScore是什么,它是怎样实现的。

3、调试技巧。

调试的时候我一般都是用F10和F20进行调试,问老师的时候又学到了设置断点的方法调试程序,这样可以通过猜想,对某一段代码进行调试,省去了很多步骤。

4、分析问题的技巧。

这个和设置断点的方法类似,例如在判断打开文件是否成功时,由于有三个函数要打开和关闭文件,而且从无提示都一样:文件打开失败。

这样在运行程序时,如果文件真的打开失败了,就很难知道哪块函数出问题了,所以可以设置不同的提示信息,来很清楚的追踪到程序的运行,还有就是发送错误报告,这种问题出现时总感觉不知道如何下手修改,因为很难知道错误的发生点,这是我们就可以设置输出提示信息:“程序已经运行到这里了”这样我们就可以从它是否输出该提示信息来了解程序是否正常运行。

相关主题