综合算法设计实验报告.docx

上传人:b****1 文档编号:14537855 上传时间:2023-06-24 格式:DOCX 页数:28 大小:294.16KB
下载 相关 举报
综合算法设计实验报告.docx_第1页
第1页 / 共28页
综合算法设计实验报告.docx_第2页
第2页 / 共28页
综合算法设计实验报告.docx_第3页
第3页 / 共28页
综合算法设计实验报告.docx_第4页
第4页 / 共28页
综合算法设计实验报告.docx_第5页
第5页 / 共28页
综合算法设计实验报告.docx_第6页
第6页 / 共28页
综合算法设计实验报告.docx_第7页
第7页 / 共28页
综合算法设计实验报告.docx_第8页
第8页 / 共28页
综合算法设计实验报告.docx_第9页
第9页 / 共28页
综合算法设计实验报告.docx_第10页
第10页 / 共28页
综合算法设计实验报告.docx_第11页
第11页 / 共28页
综合算法设计实验报告.docx_第12页
第12页 / 共28页
综合算法设计实验报告.docx_第13页
第13页 / 共28页
综合算法设计实验报告.docx_第14页
第14页 / 共28页
综合算法设计实验报告.docx_第15页
第15页 / 共28页
综合算法设计实验报告.docx_第16页
第16页 / 共28页
综合算法设计实验报告.docx_第17页
第17页 / 共28页
综合算法设计实验报告.docx_第18页
第18页 / 共28页
综合算法设计实验报告.docx_第19页
第19页 / 共28页
综合算法设计实验报告.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

综合算法设计实验报告.docx

《综合算法设计实验报告.docx》由会员分享,可在线阅读,更多相关《综合算法设计实验报告.docx(28页珍藏版)》请在冰点文库上搜索。

综合算法设计实验报告.docx

综合算法设计实验报告

综合算法设计实验报告

 

学生学号

学生实验报告书

 

实验课程名称

应用数据结构

开课学院

指导教师姓名

学生姓名

学生专业班级

 

2012—2013学年第2学期

实验项目名称

综合算法设计

同组者

实验日期

2013年06月18日

第一部分:

实验预习报告

1、实验目的、意义

1)掌握查找的含义

2)掌握基本查找操作的算法和实现

3)掌握动态查找算法的实现、应用场合与优缺点

4)能够针对具体问题,灵活选用适宜的查找算法

5)掌握排序的基本概念,对排序的稳定性及排序的时间复杂度有深刻的认识

6)对比折半插入排序和Shell排序的异同

7)掌握选择排序中堆排序的基本思想和算法实现

8)掌握快速排序的基本思想和算法实现

9)了解归并排序算法的基本思想和程序实现

10)了解基数排序算法的基本思想和程序实现

11)掌握Hash排序算法的基本思想和程序实现

12)在上述内容的基础上,将所有查找及排序算法整合在一个程序中

2、实验基本原理与方法

本实验涉及各类查找和排序算法。

静态查找,折半查找的思想为:

设查找表中的元素存放在数组r中,数据元素的下标范围为[low,high],要查找的关键字值为key,中间元素的下标为mid=|_(low+high)/2_|(向下取整),令key与r[mid]的关键字比较:

1若key=r[mid].key,查找成功,下标为m的记录即为所求,返回mid。

2若key

3若key>r[mid].key,所要找的记录只能在右半部分记录中,再对右半部分使用折半查找法继续进行查找,搜索区间缩小了一半。

重复上述过程,直到找到查找表中某一个数据元素的关键字的值等于给定的值key,说明查找成功;或者出现low的值大于high的情况,说明查找不成功。

动态查找,编程实现一个开放式的高校本科招生最低录取分数线的查询系统,供师生和家长等查询,高校自愿放入该校的信息,可能随时有高校加入。

要求实现的查询功能有:

①查询等于用户给定分数的高校;

②查询大于(或小于)用户给定分数的高校③查询最低录取分数线在用户给定的分数段中的高校。

直接插入排序:

将当前无序区的第一个记录插入到有序区中适当位置。

折半查找法:

在有序表中进行,先确定表的中点位置,再通过比较确定下一步查找哪个半区。

Shell排序:

先取定一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组,所有距离为d1倍数的记录放在同一个组中,在各组内进行直接插入排序;然后取第二个增量重复上述分组和排序,直至所取的增量dt=1(dt

堆排序是利用大顶堆(或小顶堆)来选取当前无序区中关键字最大(或最小)的记录实现排序

快速排序是对冒泡法的改进,其基本思想是:

通过一趟排序将待排文件分割成独立的两部分,其中一部分记录的关键字值均比另一部分记录的关键字小,然后分别对这两部分进行排序,以达到整个序列有序。

归并的思想:

将两个或两个以上的有序表合并成一个有序表。

利用归并的思想实现排序,假设初始的序列含有n个记录,可以看成n个有序的子序列,每个子序列的长度为m,然后把i(≥2)个子序列归并,得到n/i个长度为i的子序列;再继续归并,如此重复直到得到一个长度为n的有序序列为止。

通常使用的是i=2的二路归并法。

基数排序的基本思想是采用多关键字的排序。

设记录关键字R[i]由d个分量ki1,ki2,…,kid组成,设每个分量的取值范围为{ti|i=1,2,…,m,且t1

准备m个箱子,先按低位分箱再按序号一次将各个非空箱子里的记录收集起来,再对新收集起来的元素依次按较高的位分箱,直到最高位。

分箱即将第s个关键字等于ti的全部记录装入第i个箱子里。

按最高位分箱后,按序号一次将各个非空箱子里的记录收集起来,得到的元素序列就是有序的。

Hash排序是在Hash查找的基础上演变而来。

对待排序列采用单调的Hash函数,并用链地址法处理冲突,最后用一定规则收集存储好的数据从而得到有序序列。

3、主要仪器设备及耗材

安装有VC++6.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);

操作结果:

构造空队列Q

intQ_empty(QueueQ);

初始条件:

队列Q存在

操作结果:

若Q为空队列,则返回TRUE,否则FALSE

intQ_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);

......

}

图:

ADTGraph

{

数据对象:

D={ai|1<=i<=n,n>=0,ai属于ELEMTYPE类型}

类型标识符

数据关系:

R={|ai,aj属于D,1<=i<=n,1<=j<=n,其中每个元素可以有零个或多个直接前驱,可以有多个直接后继}

基本运算:

InitGraph(&g)

ClearGraph(&g)

DFS(g)

BFS(g)

.

.

.

}

1.2小问题:

A.随机数的产生:

srand()函数用于设置随机数种,rand()用于产生一个随机数。

B.数据的储存:

由于100000个int型数的数组,所以我采用了malloc()函数来动态分配一数组存储它。

对于一些特别大的数据可以用文件存储,在采用外排序的方式排序。

C.屏幕上无法显示100000条数据,故将数据存储在两个文本文件中。

一个是没排好序的,另一个是排好序后的数据。

1.3主要数据结构设计:

归并排序:

typedefintKeyType;

typedefintDataType;

typedefstruct

{KeyTypekey;/*排序码字段*/

/*DataTypeinfo;记录的其它字段*/}RecordNode;

typedefstruct

{intn;/*n为文件中的记录个数,n

RecordNoderecord[MAXNUM];}SortObject;

基数排序:

typedefintKeyType;

typedefintDataType;

typedefstructNodeRadixNode;

structNode

{KeyTypekey[D];

/*DataTypeinfo;*/

RadixNode*next;

};

typedefRadixNode*RadixList;

typedefstructQueueNode

{RadixNode*f;/*队列的头指针*/

RadixNode*e;/*队列的尾指针*/

}Queue;

Hash排序:

typedefstructhnode

{intdata;

structhnode*next;

}HNODE;

typedefstructpoint

{structhnode*pt;

}POINT;

1.4主程序流程:

主程序main()

 

输入随机数种子

 

产生随机数,并存在nonqueue.txt文件中

 

选择排序方法

 

7.哈希

6.基数

5.归并

4.快速

3.堆

2.希尔

1.折半

 

选择排序方法,并存在queue.txt文件中

 

 

退出程序

 

主函数在main.cpp中,排序算法的在各自的头文件中。

选择排序方法后,调用选择的排序方法。

1.5各函数调用关系:

rand()

BinsertSort()

 

ShellInsert()

fopen()

srand()

ShellSort()

main()

RadixSort()

HeapSort()

 

mergeSort()

QuickSort()

 

fclose()

Partition()

 

2.详细设计(实现程序模块的具体算法)

2.1主函数:

voidmain()

{

int*p,n,way,dlta[4]={5,3,2,1},L=11;

longi;

FILE*fp,*fp1;

if(!

(fp=fopen("queue.txt","w+")))

printf("打开文件queue.txt失败!

");

if(!

(fp1=fopen("nonqueue.txt","w+")))

printf("打开文件nonqueue.txt失败!

");

printf("请输入随机种子:

\n");

scanf("%d",&n);

p=(int*)malloc(MAX*sizeof(int));

for(i=1;i

{

p[i]=rand();

fprintf(fp1,"%-8d",p[i]);

}

fclose(fp1);

printf("\n\t\t******************************************\n");

printf("\t\t|请选择排序方式|\n");

printf("\t\t||\n");

printf("\t\t|1.折半插入排序算法|\n");

printf("\t\t|2.希尔排序算法|\n");

printf("\t\t|3:

堆排序算法|\n");

printf("\t\t|4.快速排序算法|\n");

printf("\t\t|5.归并排序算法|\n");

printf("\t\t|6.基数排序算法|\n");

printf("\t\t|7.哈希排序算法|\n");

printf("\t\t|0.退出程序|\n");

printf("\t\t******************************************\n");

printf("请输入你的选择:

\n");

scanf("%d",&way);

switch(way)

{

case0:

exit

(1);

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;i

vector.record[i].key=p[i+1];

mergeSort(&vector);

for(i=0;i

fprintf(fp,"%-8d",vector.record[i].key);

fclose(fp);

exit

(1);

}

case6:

{

RadixListhp;

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;i

element[i].next=&element[i+1];

element[MAX-1].next=NULL;

hp=element;

radixSort(&hp,6,10);

hp=hp->next;

while(hp)

{

fprintf(fp,"%-8d",hp->key[1]*10000+hp->key[2]*1000+hp->key[3]*100+hp->key[4]*10+hp->key[5]);

hp=hp->next;

}

fclose(fp);

exit

(1);

}

case7:

HashSort(p,MAX-1,MAX-1);break;

}

for(i=1;i

fprintf(fp,"%-8d",p[i]);

fclose(fp);

}

2.2各排序算法:

(1)归并排序:

#defineMAX100001

#defineMAXNUM100001

#defineTRUE1

#defineFALSE0

typedefintKeyType;

typedefintDataType;

typedefstruct

{KeyTypekey;/*排序码字段*/

/*DataTypeinfo;记录的其它字段*/}RecordNode;

typedefstruct

{longn;/*n为文件中的记录个数,n

RecordNoderecord[MAXNUM];}SortObject;

voidmerge(RecordNoder[],RecordNoder1[],longlow,longm,longhigh)

{longi=low,j=m+1,k=low;

while(i<=m&&j<=high)/*反复复制两个段的第一个记录中较小的*/

if(r[i].key<=r[j].key)r1[k++]=r[i++];

elser1[k++]=r[j++];

while(i<=m)r1[k++]=r[i++];/*复制第一个段的剩余记录*/

while(j<=high)r1[k++]=r[j++];/*复制第二个段的剩余记录*/

}

/*对r做一趟归并,结果放到r1中*/

voidmergePass(RecordNoder[],RecordNoder1[],longn,longlength)

{longi=0,j;/*length为本趟归并的有序子段的长度*/

while(i+2*length-1

{merge(r,r1,i,i+length-1,i+2*length-1);/*归并长length的两个子段*/

i+=2*length;}

if(i+length-1

merge(r,r1,i,i+length-1,n-1);

elsefor(j=i;j

}

voidmergeSort(SortObject*pvector)

{RecordNoderecord[MAXNUM];

longlength=1;

while(lengthn)/*一趟归并,结果存放在数组record中*/

{mergePass(pvector->record,record,pvector->n,length);

length*=2;

/*一趟归并,结果存回*/

mergePass(record,pvector->record,pvector->n,length);

length*=2;}

}

SortObjectvector;

(2)折半插入排序:

voidBinsertSort(intD[],longL)

{longi,j,l,r,m;

for(i=2;i<=L;i++)

{D[0]=D[i];

l=1;

r=i-1;

while(l<=r){m=(l+r)/2;

if(D[0]

elsel=m+1;}

for(j=i-1;j>=r+1;j--)D[j+1]=D[j];

D[r+1]=D[0];}

}

(3)Shell排序:

voidShellInsert(intD[],longL,longdk)

{longi,j;

for(i=dk+1;i<=L;i+=dk)

if(D[i]

{D[0]=D[i];

for(j=i-dk;j>0&&D[0]

D[j+dk]=D[0];}

}

voidShellSort(intD[],longL,intdlta[],longt)

{longk;

for(k=0;k

}

(4)堆排序算法:

voidHeapAdjust(intD[],longs,longm)

{longj;

D[0]=D[s];

for(j=2*s;j<=m;j*=2)

{if(j

if(D[0]>=D[j])break;/*已经符合堆定义,无须浪费时间*/

D[s]=D[j];

s=j;}/*交换,并使s指向新堆*/

D[s]=D[0];/*找到合适的地点就将原堆顶元装进去*/

}

voidHeapSort(intD[],longL)

{longi;

for(i=L/2;i>0;i--)HeapAdjust(D,i,L);/*将原始序列调整为堆*/

for(i=L;i>1;i--){D[0]=D[1];

D[1]=D[i];

D[i]=D[0];

HeapAdjust(D,1,i-1);}

}

(5)快速排序算法:

intPartition(intD[],longl,longr)

{D[0]=D[l];

while(l

D[l]=D[r];

while(l=D[l])l++;

D[r]=D[l];}

D[r]=D[0];

returnr;

}

voidQsort(intD[],longl,longr)

{longp;

if(l

Qsort(D,l,p-1);

Qsort(D,p+1,r);}

}

voidQuickSort(intD[],longL)

{Qsort(D,1,L);

}

(6)基数排序:

typedefintKeyType;

typedefintDataType;

typedefstructNodeRadixNode;

structNode

{

KeyTypekey[6];/*DataTypeinfo;*/

RadixNode*next;

};

typedefRadixNode*RadixList;

typedefstructQueueNode

{

RadixNode*f;/*队列的头指针*/

RadixNode*e;/*队列的尾指针*/

}Queue;

Queuequeue[10];

voidradixSort(RadixList*plist,intd,intr)

{

inti,j,k;

RadixNode*p,*head=(*plist)->next;

for(j=d-1;j>=0;j--)/*进行d次分配和收集*/

{

p=head;

for(i=0;i

{

queue[i].f=NULL;

qu

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

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2