准备m个箱子,先按低位分箱再按序号一次将各个非空箱子里的记录收集起来,再对新收集起来的元素依次按较高的位分箱,直到最高位。
分箱即将第s个关键字等于ti的全部记录装入第i个箱子里。
按最高位分箱后,按序号一次将各个非空箱子里的记录收集起来,得到的元素序列就是有序的。
Hash排序是在Hash查找的基础上演变而来。
对待排序列采用单调的Hash函数,并用链地址法处理冲突,最后用一定规则收集存储好的数据从而得到有序序列。
3、主要仪器设备及耗材
安装有TurboC++3.0运行环境的电脑,无耗材要求。
4、实验方案或技术路线
本实验含有五部分内容——静态查找、动态查找、插入排序与选择排序、快速排序与归并排序、查找及排序算法集成。
A.静态查找部分
查找表的存储结构为有序表,即表中记录按关键字大小排序存放。
输入待查数据元素的关键字进行查找。
为了简化算法,记录只含一个整型量关键字字段,记录的其余数据部分忽略不考虑。
此程序中要求对整型量关键字数据的输入按从小到大排序输入。
B.动态查找部分
主要的功能是查找,查找表为高校最低录取分数信息的集合。
根据题意可知,该查找表中的元素个数可能随时增减,所以它是一个动态查找表,可采用树状结构保存。
为了提高查询速度,可建立二叉排序树并在二叉排序树中实现查找。
C.排序部分
考虑对20个整数的随机输入进行排序,各排序功能基本上都可以成为独立调用的模块,因此可以先写出排序算法,然后用主函数调用。
D.查找及排序算法集成部分
此部分需要学生自行设计,本指导书不给出具体算法。
第二部分:
实验过程记录
实验原始记录(包括实验数据记录,实验现象记录,实验过程发现的问题等)
1.概要设计(说明本程序中用到的所有抽象数据类型的定义,主程序的流程以及各程序模块之间的层次或调用关系)
1.1抽象数据类型
队列:
ADTQueue{数据对象:
D={ai|ai∈ElemSet,i=1,2,...,n,n≥0}数据关系:
R1={|ai-1,ai∈D,i=2,...,n}基本操作:
voidinit_Q(Queue&Q);操作结果:
构造空队列QintQ_empty(QueueQ);初始条件:
队列Q存在操作结果:
若Q为空队列,则返回TRUE,否则FALSEintQ_length(QueueQ);初始条件:
队列Q存在操作结果:
返回队列Q的元素个数,即队列长度intgethead_Q(QueueQ);初始条件:
队列Q存在操作结果:
返回队列Q的队头元素voiden_Q(Queue&Q,inte);初始条件:
队列Q存在操作结果:
插入元素e为Q的新的队尾元素。
voidde_Q(Queue&Q,int&e);初始条件:
队列Q存在操作结果:
删除Q的队头元素。
}ADTQueue
线性表:
ADTList
{
数据对象:
D={ai|1<=i<=n,n>=o,ai属于elementtype类型}
数据关系:
R={|ai,ai+1属于D,i=1,...,n-1}
基本运算:
InitList(&l)
DestroyList(&l);
......
}
1.2主程序流程
1.3各程序模块之间的调用关系
2.详细设计(实现程序模块的具体算法)
2.1数据类型
归并排序:
typedefintKeyType;
typedefintDataType;
typedefstruct
{
KeyTypekey;/*排序码字段*/
DataTypeinfo;/*记录的其它字段*/
}RecordNode;
typedefstruct
{intn;/*n为文件中的记录个数,nRecordNoderecord[MAXNUM];
}SortObject;
基数排序:
typedefintKeyType;
typedefintDataType;
typedefstructNodeRadixNode;
structNode
{
KeyTypekey[D];
RadixNode*next;
};
typedefRadixNode*RadixList;
typedefstructQueueNode
{
RadixNode*f;/*队列的头指针*/
RadixNode*e;/*队列的尾指针*/
}Queue;
Queuequeue[R];
哈希排序:
typedefstructhnode
{intdata;
structhnode*next;
}HNODE;
typedefstructpoint
{structhnode*pt;
}POINT;
2.2主函数详细代码
voidmain()
{
intflag=0;//定义操作指示码
int*p,way,dlta[4]={5,3,2,1},L=11,randint;
RadixListhp=element;
longi;
FILE*fp1,*fp2;
if(!
(fp1=fopen("BeforeOrder.txt","w+")))
printf("cannotopenthefileBeforeOrder.txt!
");
if(!
(fp2=fopen("AfterOrder.txt","w+")))
printf("cannotopenthefileAfterOrder.txt!
");
printf("***请输入随机数种******\n");
scanf("%d",&randint);
srand(randint);
p=(int*)malloc(MAX*sizeof(int));
for(i=1;i{
p[i]=rand();
fprintf(fp1,"%-8d",p[i]);
}
fclose(fp1);
printf("***请选择一种排序算法******\n");
printf("***1--折半插入排序******\n");
printf("***2--Shell排序******\n");
printf("***3--堆排序******\n");
printf("***4--快速排序******\n");
printf("***5--归并排序******\n");
printf("***6--基数排序******\n");
printf("***7--Hash排序******\n");
printf("请选择:
");
//读取指示码
scanf("%d",&flag);
switch(flag)
{
case1:
BinsertSort(p,MAX-1);break;
case2:
ShellSort(p,MAX-1,dlta,4);break;
case3:
HeapSort(p,MAX-1);break;
case4:
QuickSort(p,MAX-1);break;
case5:
vector.n=MAX-1;
for(i=0;ivector.record[i].key=p[i+1];
mergeSort(&vector);
for(i=0;ifprintf(fp2,"%-8d",vector.record[i].key);
fclose(fp2);
printf("成功了!
\n");
exit
(1);
case6:
for(i=0;i{
element[i].key[0]=0;
element[i].key[1]=p[i+1]/10000%10;
element[i].key[2]=p[i+1]/1000%10;
element[i].key[3]=p[i+1]/100%10;
element[i].key[4]=p[i+1]/10%10;
element[i].key[5]=p[i+1]%10;
element[i].next=NULL;
}
for(i=0;ielement[MAX-1].next=NULL;
radixSort(&hp,6,10);
hp=hp->next;
while(hp){fprintf(fp2,"%-8d",hp->key[1]*10000+hp->key[2]*1000+hp->key[3]*100+hp->key[4]*10+hp->key[5]);
hp=hp->next;}
fclose(fp2);
printf("成功了!
\n");
exit
(1);
case7:
HashSort(p,intL,M);
}
//保存排序结果
for(i=1;ifprintf(fp2,"%-8d",p[i]);
fclose(fp2);
printf("成功了!
\n");
getchar();
}
3.调试分析(内容包括:
a)调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析;b)算法的时空分析——包括基本操作和相关算法的时间复杂度和空间复杂度的分析以及改进设想;c)经验和体会等)
3.1问题回顾与分析
1)开始使用rand函数产生随机数的时候,会发现生成的随机数每一次的运行都是一样的。
后发现是因为没有随机数种的原因,所以系统的每一次运行,都应该让用户输入一个随机数种,使用srand()函数进行设置,就可以解决这个问题。
2)对100000个随机数进行排序的时候,可能时间会有点长。
3)要生成100000个随机数,MAX的值就应该是100001,因为很多的排序算法中,都用数组的第一个索引来存储临时变量。
4)哈希排序的内存泄露问题还没有解决。
3.2算法的时空分析:
3.3经验体会:
记得大一学习C语言的时候,只接触过两种简单的排序算法,而且效率都是O(n*n)。
当我接触到快速排序和哈希排序时,就为它的精髓所深深吸引到。
好的一个排序算法,不仅要考虑到比较的次数,还要考虑它的赋值次数。
经过这一次的实验,我对排序的算法有了更深一次的了解。
以前学到的更多是理论知识,动手的机会不是很多,正是这一次的实验激发了我对数据结构的兴趣,数据结构弄懂了,编程的思想就提高了一个台阶,以后碰到什么问题,都有一个方向去解决。
第三部分结果与讨论
实验结果分析(包括数据处理、实验现象分析、影响因素讨论、综合分析和结论等)
程序设计类实验:
包括原程序、输入数据、运行结果、实验过程发现的问题及解决方法等;
分析与设计、软件工程类实验:
编制分析与设计报告,要求用标准的绘图工具绘制文档中的图表。
系统实施部分要求记录核心处理的方法、技巧或程序段;
其它实验:
记录实验输入数据、处理模型、输出数据及结果分析
测试结果(列出测试结果,包括输入和输出。
这里的测试数据应该完整而严格,最好多于需求分析中所列)
1、输入随机数种
2、选择排序类型
3文件BeforeOrder.txt中的内容
4文件AfterOrder.txt中的内容
-----------------------------------------------------------------------
实验报告评语及成绩(请按优,良,中,及格,不及格五级评定)
教师签字: