数据结构实验报告查找最高分与次高分.docx

上传人:b****9 文档编号:25700452 上传时间:2023-06-11 格式:DOCX 页数:14 大小:27.31KB
下载 相关 举报
数据结构实验报告查找最高分与次高分.docx_第1页
第1页 / 共14页
数据结构实验报告查找最高分与次高分.docx_第2页
第2页 / 共14页
数据结构实验报告查找最高分与次高分.docx_第3页
第3页 / 共14页
数据结构实验报告查找最高分与次高分.docx_第4页
第4页 / 共14页
数据结构实验报告查找最高分与次高分.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

数据结构实验报告查找最高分与次高分.docx

《数据结构实验报告查找最高分与次高分.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告查找最高分与次高分.docx(14页珍藏版)》请在冰豆网上搜索。

数据结构实验报告查找最高分与次高分.docx

数据结构实验报告查找最高分与次高分

 

数据结构与程序设计实验

实验报告

课程名称

数据结构与程序设计实验

课程编号

0906550

实验项目名称

查找最高分与次高分

学号

年级

姓名

专业

计算机科学与技术

学生所在学院

计算机学院

指导教师

杨静

实验室名称地点

21B276

哈尔滨工程大学

实验报告六

实验课名称:

数据结构与程序设计实验

实验名称:

查找最高分与次高分

班级:

学号:

姓名:

时间:

2016.05.05

一、问题描述

有512人参与玩某游戏,从1~512给每个人分配一个编号,每个人的游戏得

分在0~999之间,现要用不同方法查找出游戏参与者的最高分和次高分。

要求:

a.自行产生512个的随机整数作为所有游戏参与者的得分。

b.输出所有游戏参与者(用编号表示)及其得分。

c.用顺序查找方法查找出其中取得最高分和次高分者及其分数,并输出。

d.锦标赛法查找出其中取得最高分和次高分者及其分数,并输出。

e.通过无序序列建堆和堆调整得到取得最高分者和次高分者及其分数,并输出。

f.比较不同方法的查找效率和各自的特点。

二、数据结构设计

1.使用结构体People存储序号和得分,表示个体

typedefstruct{

intnum;

intscore;

}People;

2.设置MIN表示People数据类型的最小值,用于竞标赛查找

#defineIN_MAX(int)(((unsigned)(~((int)0)))>>1)

#defineIN_MIN(-IN_MAX-1)

constPeopleMIN={513,IN_MIN};

3.使用结构体Peoples作为顺序表,存储每个个体

typedefstruct{

People*base;

intlength;

}Peoples;

三、算法设计

1.顺序查找

intsearch(Peoples*p){

Peoplebigger=p->base[1];

Peoplebiggest=p->base[1];

intn;

for(n=1;n<=512;n++){

if(p->base[n].score>biggest.score){

bigger=biggest;

biggest=p->base[n];

}elseif(p->base[n].score>bigger.score){

bigger=p->base[n];

}

if(p->base[n].num!

=biggest.num&&p->base[n].score==biggest.score){

printf("第%d人和第%d人的分数一样大\n",p->base[n].num,biggest.num);

}

}

printf("第%d人的的分数最大:

%d\n",biggest.num,biggest.score);

printf("第%d人的的分数次大:

%d\n",bigger.num,bigger.score);

return0;

}

2.锦标赛查找

(a).每次将最大值选择至树根后调整树

voidAdjust(Peoples*p,intx,intn){

intl=x*2;//左子树

intr=l+1;//右子树

if(l>=n){//x为叶子节点

p->base[x]=MIN;

return;

}elseif(r>=n){//x有左子树,无右子树

p->base[x]=p->base[l];

return;

}

if(p->base[l].num==p->base[x].num){

Adjust(p,l,n);

}else{

Adjust(p,r,n);

}

p->base[x]=max(p->base[l],p->base[r]);

}

(b).初始树并依次查找最大值与最大值

voidGameSort(Peoples*a,intn){

inti,len;

Peoples*b;

b=(Peoples*)malloc(sizeof(Peoples));

len=1;

while(len

len<<=1;//len为偶数

//printf("len:

%d",len);

}

len=2*len;

//printf("len:

%d\n",len);

b->base=(People*)malloc(sizeof(People)*len);

b->length=len;

for(i=len/2;i

b->base[i]=(i-len/2

(a->base[i-len/2]):

(MIN);

}

for(i=len/2-1;i>=1;i--){//在双亲存放左右最大值

b->base[i]=max(b->base[2*i],b->base[2*i+1]);

}

for(i=1;i<=2;i++){//只调整前两个顺序,依次将树根前置

a->base[i]=b->base[1];

Adjust(b,1,len);

}

printf("第%d人的的分数最大:

%d\n",a->base[1].num,a->base[1].score);

printf("第%d人的的分数次大:

%d\n",a->base[2].num,a->base[2].score);

free(b);

}

3.通过无序序列建堆和堆调整得到取得最高分者和次高分者及其分数

(a).筛选:

除p->base[s]外均满足堆定义,调整p->base[s],将p->base[s,m]建立为大顶堆

intHeapAdjust(Peoples*p,ints,intm){

Peoplerc=p->base[s];

intj;

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

if(jbase[j].scorebase[j+1].score)){

++j;//j指向较大的孩子节点

}

if(!

(rc.scorebase[j].score)){

break;

}

p->base[s]=p->base[j];

s=j;

}

p->base[s]=rc;

return0;

}

(b).对p->base[1..512]建堆,进行堆调整取得最高分和次高分者,并输出

intHeapSort(Peoples*p){

inti;

for(i=(p->length)/2;i>0;--i){//从最后一个非叶子节点开始,建立大顶堆

HeapAdjust(p,i,p->length);

}

for(i=p->length;i>510;--i){//只将最大和次大的得分交换到末尾

swap(p->base[1],p->base[i]);

HeapAdjust(p,1,i-1);

}

printf("第%d人的的分数最大:

%d\n",p->base[512].num,p->base[512].score);

printf("第%d人的的分数次大:

%d\n",p->base[511].num,p->base[511].score);

return0;

}

四、运行测试与分析

1.开始运行后,自行产生512个的随机整数作为所有游戏参与者的得分,并输出所有游戏参与者(用编号表示)及其得分。

2.省略中间部分,余下输出

3.输出顺序查找,锦标赛查找,堆排序查找的结果

五、实验收获与思考

通过本次实验,巩固了关于查找算法的知识,同时在编程过程中发现了自己的不足,遇到了很多语法错误及逻辑错误,通过不断的调试解决问题,使我对编程有了更加深入的体会和认识。

顺序查找,锦标赛查找,堆查找的效率及特点:

如果有n个待查找元素,顺序查找每次查找均需进行n-1次比较,但不需额外存储空间。

锦标赛排序构成的树是满的完全二叉树,深度为log2n+1,除第一次选择具有最大关键码的记录需要进行n-1次比较外,重构树选择具有次小、再次小关键码记录所需的比较次数均为O(log2n),但这种选择方法虽然减少了许多查找时间,但是使用了较多的附加存储。

堆查找的运行时间主要耗费在初始和调整堆时进行的反复筛选上,堆查找仅需记录一个大小供交换的辅助存储空间,每个记录仅占有一个存储空间。

六、源代码

#include

#include

#include

#definemax(x,y)(((x.score)>(y.score)?

(x):

(y)))

#defineIN_MAX(int)(((unsigned)(~((int)0)))>>1)

#defineIN_MIN(-IN_MAX-1)

typedefstruct{

intnum;

intscore;

}People;

typedefstruct{

People*base;

intlength;

}Peoples;

constPeopleMIN={513,IN_MIN};

People_;

#defineswap(x,y){_=x;x=y;y=_;}

intinit_all_people(Peoples*p){

intn;

srand((unsigned)time(NULL));//设置每个人的成绩为随机值

for(n=1;n<=512;n++){

p->base[n].num=n;

p->base[n].score=rand()%1000;

}

p->length=512;

return0;

}

intcopy_people(Peoples*p1,Peoples*p2){

intn;

for(n=1;n<=512;n++){

p2->base[n].num=p1->base[n].num;

p2->base[n].score=p1->base[n].score;

}

p2->length=p1->length;

return0;

}

intdisplay(Peoples*p){

intn;

for(n=1;n<=512;n++){

printf("第%3d个人的分数是%3d",p->base[n].num,p->base[n].score);

if(n%2==0)printf("\n");

}

return0;

}

//顺序查找

intsearch(Peoples*p){

Peoplebigger=p->base[1];

Peoplebiggest=p->base[1];

intn;

for(n=1;n<=512;n++){

if(p->base[n].score>biggest.score){

bigger=biggest;

biggest=p->base[n];

}elseif(p->base[n].score>bigger.score){

bigger=p->base[n];

}

if(p->base[n].num!

=biggest.num&&p->base[n].score==biggest.score){

printf("第%d人和第%d人的分数一样大\n",p->base[n].num,biggest.num);

}

}

printf("第%d人的的分数最大:

%d\n",biggest.num,biggest.score);

printf("第%d人的的分数次大:

%d\n",bigger.num,bigger.score);

return0;

}

//锦标赛排序--输出后调整

intAdjust(Peoples*p,intx,intn){

intl=x*2;//左子树

intr=l+1;//右子树

if(l>=n){//x为叶子节点

p->base[x]=MIN;

return0;

}elseif(r>=n){//x有左子树,无右子树

p->base[x]=p->base[l];

return0;

}

if(p->base[l].num==p->base[x].num){

Adjust(p,l,n);

}else{

Adjust(p,r,n);

}

p->base[x]=max(p->base[l],p->base[r]);

return0;

}

intGameSort(Peoples*a,intn){

inti,len;

Peoplesb;

len=1;

while(len

len<<=1;//len为偶数

}

len=2*len;

//printf("len:

%d\n",len);

b.base=(People*)malloc(sizeof(People)*len);

b.length=len;

for(i=len/2;i

b.base[i]=(i-len/2

(a->base[i-len/2]):

(MIN);

}

for(i=len/2-1;i>=1;i--){//在双亲存放左右最大值

b.base[i]=max(b.base[2*i],b.base[2*i+1]);

}

for(i=1;i<=2;i++){//只调整前两个顺序,依次将树根前置

a->base[i]=b.base[1];

Adjust(&b,1,len);

}

printf("第%d人的的分数最大:

%d\n",a->base[1].num,a->base[1].score);

printf("第%d人的的分数次大:

%d\n",a->base[2].num,a->base[2].score);

return0;

}

/*

*堆排序--筛选

*只有p->base[s]不符合规定,将p->base[s,m]建立为大顶堆

*/

intHeapAdjust(Peoples*p,ints,intm){

Peoplerc=p->base[s];

intj;

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

if(jbase[j].scorebase[j+1].score)){

++j;//j指向较大的孩子节点

}

if(!

(rc.scorebase[j].score)){

break;

}

p->base[s]=p->base[j];

s=j;

}

p->base[s]=rc;

return0;

}

/*

*对p->base[1..512]进行堆排序,只将最大和次大交换到末尾

*/

intHeapSort(Peoples*p){

inti;

for(i=(p->length)/2;i>0;--i){//从最后一个非叶子节点开始,建立大顶堆

HeapAdjust(p,i,p->length);

}

for(i=p->length;i>510;--i){//只将最大和次大的得分交换到末尾

swap(p->base[1],p->base[i]);

HeapAdjust(p,1,i-1);

}

printf("第%d人的的分数最大:

%d\n",p->base[512].num,p->base[512].score);

printf("第%d人的的分数次大:

%d\n",p->base[511].num,p->base[511].score);

return0;

}

intmain(){

Peoplesp1;

p1.base=(People*)malloc(sizeof(People)*513);

Peoplesp2;

p2.base=(People*)malloc(sizeof(People)*513);

Peoplesp3;

p3.base=(People*)malloc(sizeof(People)*513);

init_all_people(&p1);

copy_people(&p1,&p2);

copy_people(&p1,&p3);

display(&p1);

printf("\n顺序查找:

\n");

search(&p1);

printf("\n锦标赛查找:

\n");

GameSort(&p2,513);

printf("\n堆排序查找:

\n");

HeapSort(&p3);

free(p1.base);

free(p2.base);

free(p3.base);

return0;

}

教师评分:

 

教师签字:

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

当前位置:首页 > 医药卫生 > 临床医学

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

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