实习.docx
《实习.docx》由会员分享,可在线阅读,更多相关《实习.docx(33页珍藏版)》请在冰豆网上搜索。
![实习.docx](https://file1.bdocx.com/fileroot1/2023-5/23/e466f622-c048-47b7-9efd-d2c70fe5cccd/e466f622-c048-47b7-9efd-d2c70fe5cccd1.gif)
实习
数据结构计算实习报告
班级:
学号:
姓名:
--------------------2011.7.4
实习题目:
2.6.3
一实习目的
(1)、综合这学期数据结构课知识,自己设计编程,锻炼的综合编程能力
(2)、加强模块化编程思想;(3)、让同学们熟练各种排序方法;使同学们实现由编辑单个的小程序到编辑相对较大的多功能程序的转变。
二问题定义及题目分析
1.题目定义:
(1)(2.6.3.1—2.6.3.3)编程实现插入、希尔、冒泡、快速、选择、堆排序并进行比较分析.
(2)(2.6.3.4)宿舍管理管理查询软件。
(3)(2.6.3.5)统计成绩
2.题目分析:
(1)根据题目要求,分别使用六种不同方法对指定数据进行排序,六种方法分模块化设计,总函数根据用户选择调用相应模块。
(2)该题目要求利用三种不同关键字实现学生信息的查询。
(3)利用一种排序方法对学生成绩信息进行排序,并要求分数相同的排名相同。
三概要设计
(1)(2.6.3.1—2.6.3.3)编程实现插入、希尔、冒泡、快速、选择、堆排序并进行比较分析
qSqlistCreat(charfilename[])//打开文件,创建链表
voidprint(qSqlistL)//将已排好序的数据存到指定文件
qSqlistShellSort(qSqlistL)//希尔排序
qSqlistQsort(qSqlistL,intlow,inthigh)//对顺序表的子序列L.r[low..high]作快速排序
qSqlistInsertSort(qSqlistL)//直接插入排序
qSqlistHeapSort(qSqlistH)//堆排序
qSqlistBubbleSort(qSqlistL)//冒泡排序
qSqlistSelectSort(qSqlistL)//选择排序
函数调用关系
输入输出:
输入为数据文件(.txt),输出为数据文件(.txt)
(2)(2.6.3.4)宿舍管理管理查询软件
sStudentCreat(charfilename[])//创建链表
intBinarySearch1(sStudentL,charname1[])//按姓名关键字查找
intBinarySearch2(sStudentL,intn)//按学号关键字查找
intBinarySearch3(sStudentL,intn)//按宿舍号关键字查找
函数调用关系:
输入输出:
输入为学生信息文件(.txt),输出为控制台输出查询结果(格式:
姓名学号班号房号)
(3)(2.6.3.5)统计成绩
sScorelistCreat(charfilename[])//打开文件,创建链表
sScorelistSort(sScorelistL)//冒泡法实现成绩排名
sScorelistGenRank(sScorelistL)//设置排名:
分数相同的排名相同
voidPrint(sScorelistL)//输出
输入输出:
输入为指定成绩文件(.txt),输出为控制台输出经排名后的成绩单(格式:
名次姓名成绩)。
四详细设计
(1)数据结构定义:
structNode{
intkey;
};//定义结点
typedefstruct{
structNoder[MAXSIZE-1];
longlength;
}Sqlist,*qSqlist;//定义链表,及链表指针
structNode2{
structNoder;
structNode2*next;
};
六种排序方法的除了希尔排序入口参数均为qSqlistL(表示已创建的sSqlist链表),希尔排序入口参数为(qSqlistL,intdk)dk为步长。
(2)数据结构定义:
structstu
{
charname[M];
intstu_num;
intclass_num;
intdom_num;
};//定义学生数据结构
typedefstruct{
structstus[MAXSIZE-1];
intlength;
}Student,*sStudent;//定义链表及链表指针
sStudentCreat(charfilename[])入口参数为输入文件名
sStudentSortFile(sStudentL,intn)入口参数为已创建学生链表和选择排序指定关键字序号
intBinarySearch(sStudentL,intn)入口参数为已创建的学生链表和指定的关键字序号
(3)数据结构定义:
structNode{
intrank;
charname[M];
intscore;
};//定义节点
typedefstruct{
structNoder[MAXSIZE-1];
intlength;
}Scorelist,*sScorelist;//定义链表,及链表指针
除主函数外,所有函数入口参数均为sScorelistL,已创建的成绩链表
五调试与测试分析
一、程序调用过程:
主函数
输入文件名
选择排序方法
。
。
。
。
。
。
快速排序
选择排序
冒泡排序
堆排序
直接插入排序
希尔排序
排序完成
输出
键入输出文件名
存入输出文件
否
是
是否继续别的方法排序
退出
调试过程中遇到的问题及解决方法:
程序调用过程中遇到的问题主要是参数传递的以及参数调用,为了统一模块,对每个函数的参数设置为链表指针指向的已创建链表地址
测试:
测试方法:
用随机函数生成一个含有10000个随机数的txt文件,通过对它的排序过程,统计排序时间,交换次数以及比较次数,比较各排序算法的性能与效率。
测试结果:
排序方法
排序用时
交换次数
比较次数
希尔排序
0.007000s
242549
183187
快速排序
0.003000s
69208
162392
插入排序
0.189000s
9999
25036055
堆排序
0.003000s
129196
60496
冒泡排序
0.725000s
25026056
49994727
选择排序
0.326000s
9999
50004999
结果分析:
(1)比较直接插入排序和希尔排序
希尔排序用时比直接插入排序少的多,说明它的效率比直接排序高,主要体现在比较次数比直接排序算法少。
(2)比较快速排序和冒泡排序
快速排序比冒泡排序效率高,冒泡排序算法的时间复杂度是O(n2),而快速排序算法时间复杂度是O(㏒n)。
(3)比较堆排序和选择排序
堆排序效率比选择排序高,选择排序算法的时间复杂度是O(n2),而堆排序算法时间复杂度是O(n㏒n)。
二、
测试:
测试结果分析:
查询准确
三、
测试:
测试结果分析:
成绩排名符合题目要求
六结果分析及总结
完成本大题要求的5个小题,共用了3个程序,第一个程序包含前3小题的内容,运行结果均符合要求。
排序算法选择的不同,结果会差别很大,这主要源于算法复杂度的不同,所以对大规模数据进行排序时,选择一个高效率的算法很重要。
其次,选择一个合适的数据结果对程序的效率也有很重要。
七附录
Sort.cpp实现插入、希尔、冒泡、快速、选择、堆排序的算法,它的输入为txt文件(文件中储存数据data.txt),输出为txt文件;
DomSearch.cpp实现宿舍管理查询,可以根据姓名、学号、房号等不同关键字进行查询学生信息,该程序的输入为txt文件(存储学生信息student.txt),输出为查询结果;
ScoreRank.cpp实现对给定学生成绩排序,并按名次输出成绩,而且分数相同时名次相同,该程序输入为成绩txt文件(score.txt),输出为名次排序结果。
程序一Sort.cpp:
#include"stdio.h"
#include"malloc.h"
#include"stdlib.h"
#include"time.h"
#include"math.h"
#defineMAXSIZE10000000
#defineMAXNUM20000000
#defineM20
#defineLensizeof(Sqlist)
longshifttimes;//交换次数
longcomparetimes;//比较次数
clock_tstart,finish;//定义时间变量
doubleduration;
structNode{
intkey;
};//定义结点
typedefstruct{
structNoder[MAXSIZE-1];
longlength;
}Sqlist,*qSqlist;//定义链表,及链表指针
structNode2{
structNoder;
structNode2*next;
};
typedefstruct{
intkey;//关键字
intotherinfo;//其他信息
}rectype;
qSqlistCreat(charfilename[])//打开文件,创建链表
{
FILE*fp;
longi;
qSqlistL;
L=(qSqlist)malloc(Len);
L->length=0;
fp=fopen(filename,"r");
if(!
fp){
printf("cannotopenthisfile\n");
exit(0);
}
for(i=1;i{
fscanf(fp,"%d\n",&(L->r[i].key));
if(L->r[i].key<0)break;
L->length++;//记录文件长度
}
fclose(fp);
return(L);
}
voidprint(qSqlistL)//将已排好序的数据存到指定文件
{
FILE*p;
longi;
charfilename1[M];
printf("Pleaseinputthestoringfile(sample:
out.txt):
\n");
scanf("%s",filename1);//输入要存入文件的名字
if((p=fopen(filename1,"wt"))==NULL)//打开文件
{
printf("cannotopenthisfile\n");
exit(0);
}
for(i=1;ilength+1;++i)//写入文件
{
fprintf(p,"%d\n",L->r[i].key);
}
fclose(p);
}
voidprint1(qSqlistL)//输出排序相关的数据
{
printf("\n\t\tthelengthofthefileis:
%ld",L->length);
printf("\n\t\ttheshifttimesis:
%ld",shifttimes);
printf("\n\t\tthecomparetimesis:
%ld",comparetimes);
printf("\n\t\tthetimeusedis:
%fs\n",duration/1000);
}
//***************************************************************希尔排序
qSqlistShellinsert(qSqlistL,intdk)
{
inti,j;
for(i=dk+1;i<=L->length;++i)
if(LT(L->r[i].key,L->r[i-dk].key)){//需将L->r[i]插入有序增量链表
comparetimes++;
L->r[0]=L->r[i];//暂存在L->r[0]
shifttimes++;
for(j=i-dk;j>0&<(L->r[0].key,L->r[j].key);j-=dk){
L->r[j+dk]=L->r[j];//记录后移
comparetimes++;
shifttimes++;
}
L->r[j+dk]=L->r[0];//插入
shifttimes++;
}
return(L);
}
qSqlistShellSort(qSqlistL)//希尔排序
{
inti,t=0;
intk;
start=clock();
for(t=0;LQ(pow(2,t),(L->length+1));t++);
t=t-1;
for(i=1;i<=t;++i)
{
k=(int)pow(2,t-i+1)-1;//计算排序增量
L=Shellinsert(L,k);
}
finish=clock();
duration=(double)(finish-start);//计算耗时
print1(L);
print(L);
return(L);
}
//*****************************************************************快速排序
longPartition(qSqlistL,intlow,inthigh)
{//交换顺序表L中子表r[low..high]的记录,枢纽记录到位,并返回其所在位置,此时在它之前(后)的记录均不大(小)于它
intpivotkey;
L->r[0]=L->r[low];//用子表的第一个记录做枢纽记录
pivotkey=L->r[low].key;//枢纽记录关键字
while(lowwhile(lowr[high].key>=pivotkey){
comparetimes++;
--high;}
L->r[low]=L->r[high];//比枢纽小的记录到低端
shifttimes++;
while(lowr[low].key<=pivotkey){
comparetimes++;
++low;}
L->r[high]=L->r[low];//比记录大的记录到高端
shifttimes++;
}
comparetimes++;
L->r[low]=L->r[0];//枢纽记录到位
shifttimes++;
returnlow;//返回枢纽位置
}
qSqlistQsort(qSqlistL,intlow,inthigh)
{//对顺序表的子序列L.r[low..high]作快速排序
intpivotloc;
if(lowpivotloc=Partition(L,low,high);//将L->r[low..high]一分为二
Qsort(L,low,pivotloc-1);//对低子表递归排序
Qsort(L,pivotloc+1,high);//对高子表递归排序
}
return(L);
}
qSqlistQuickSort(qSqlistL)//快速排序
{//对顺序表L作快速排序
start=clock();
Qsort(L,1,L->length);
finish=clock();
duration=double(finish-start);//时间变量
print1(L);
print(L);
return(L);
}
//******************************************************************************直接插入排序
qSqlistInsertSort(qSqlistL)//直接插入排序
{
inttemp;
longi,j;
start=clock();
for(i=1;ilength;i++)
{
temp=L->r[i].key;
for(j=i-1;j>=0;j--)
{
comparetimes++;
if(L->r[j].key<=temp)
break;
elseL->r[j+1].key=L->r[j].key;
}
L->r[j+1].key=temp;
shifttimes++;
}
finish=clock();
duration=(double)(finish-start);
print1(L);
print(L);
return(L);
}
//*****************************************************************************堆排序
qSqlistHeapadjust(qSqlistH,ints,intm)
{
intj;
structNoderc;
rc=H->r[s];
for(j=2*s;j<=m;j*=2){//沿key较大的孩子节点向下筛选
if(jr[j].key,H->r[j+1].key)){//j为key较大的记录的坐标
comparetimes++;
++j;}
if(!
LT(rc.key,H->r[j].key)){//rc应插在位置s上
comparetimes++;break;
}
H->r[s]=H->r[j];
shifttimes++;
s=j;
}
H->r[s]=rc;//插入
shifttimes++;
return(H);
}
qSqlistHeapSort(qSqlistH)//堆排序
{
inti;
structNodetmp;
start=clock();
for(i=H->length/2;i>0;--i)//把H.r[1..H,length]建成大顶堆
Heapadjust(H,i,H->length);
for(i=H->length;i>1;--i)
{
tmp=H->r[1];//将堆顶记录和当前未经排序子序列Hr[1..r]中最后一个记录想交换
H->r[1]=H->r[i];
H->r[i]=tmp;
Heapadjust(H,1,i-1);//将H.r[1..i-1]重新调整为大顶堆
}
finish=clock();
duration=(double)(finish-start);
print1(H);
print(H);
return(H);
}
//********************************************************************************冒泡排序
qSqlistBubbleSort(qSqlistL)//冒泡排序
{
inti,j,temp,exchangeCnt;
start=clock();
for(i=0;i<=L->length;i++)
{
exchangeCnt=0;
for(j=0;jlength-i-1;j++)
{
comparetimes++;
if(L->r[j].key>L->r[j+1].key)
{
shifttimes++;
temp=L->r[j].key;
L->r[j].key=L->r[j+1].key;
L->r[j+1].key=temp;
exchangeCnt++;
}
}
if(exchangeCnt==0)
break;
}
finish=clock();
duration=(double)(finish-start);
print1(L);
print(L);
return(L);
}
//*********************************************************************************选择排序
qSqlistSelectSort(qSqlistL)//选择排序
{
inti,j;
inttemp,k;
start=clock();
for(i=0;ilength-1;i++)
{
for(j=i,k=j;jlength;j++)
{
comparetimes++;
if(L->r[j].keyr[k].key)
k=j;
}
shifttimes++;
temp=L->r[i].key;
L->r[i].key=L->r[k].key;
L->r[k].key=temp;
}
finish=clock();
duration=(double)(finish-start);
print1(L);
print(L);
return(L);
}
voidmain()
{
charfilename2[M];
FILE*q;
inti,j;
qSqlistL;
printf("pleaseinputtheselectedfileyouwanttosort(sample:
int.txt):
\n");
gets(filename2);//输入要排序的文件名
if(!
(q=fopen(filename2,"r"))){
printf("cannotopenthisfile\n");
exit(0);
}
loop1:
//goto循环
L=Creat(filename2);//创建链表
//输出界面
printf("\n\n\t**************************************************************");