排序算法性能分析说明书.docx
《排序算法性能分析说明书.docx》由会员分享,可在线阅读,更多相关《排序算法性能分析说明书.docx(23页珍藏版)》请在冰豆网上搜索。
![排序算法性能分析说明书.docx](https://file1.bdocx.com/fileroot1/2023-1/2/566c2988-af1d-42f9-80d0-c25fd29b57f9/566c2988-af1d-42f9-80d0-c25fd29b57f91.gif)
排序算法性能分析说明书
*******************
实践教学
*******************
兰州理工大学
计算机与通信学院
2012年春季学期
算法与数据结构课程设计
题目:
排序算法性能分析
专业班级:
10级软件工程基地班
姓名:
学号:
10250138
指导教师:
王旭阳
成绩:
目录
摘要1
1.采用类c语言定义相关的数据类型2
2.各模块的伪码算法2
3.函数的调用关系图6
4.调试分析7
5.测试结果8
6.源程序(带注释)11
总结15
参考文献16
致谢17
附件Ⅰ任务一源程序代码18
摘要
计算机的日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及插入、删除、排序、查找等复杂的非数值处理和操作。
算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。
《算法与数据结构》主要介绍一些最常用的数据结构及基本算法设计,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。
数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程。
它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。
本次的课程设计主要是对《算法与数据结构》的所有内部排序算法进行了一个汇总、集合,并通过算法设计实现对其性能的分析和评价。
在设计过程中重温了C语言中的基本语法以及个别函数的用法,巩固了设计思维方向。
关键词:
排序算法;性能分析;排序算法性能分析;
1.采用类c语言定义相关的数据类型
#defineN1000//定义数组最大为100
constintt=3;//定义希尔排序次数
intd[3]={4,3,1};//定义希尔排序比较量
intm;
intqmt;//快速排序的移动次数
intqct;//快速排序的比较次数printf("%d\t",)
2.各模块的伪码算法
(1)直接插入排序
InsertSort(RecordnodeR[],intn)
{
for(i=2;<=n;++i)
if(R[i]{
R[0]=R[i];
for(j=i-1;R[0]R[j+1]=R[j];//记录后移
R[j+1]=R[0];//插入到正确位置
}
}
(2)折半插入排序
BinsertSort(RecordnodeR[],intn)
{
for(i=2;<=n;++i)
{
R[0]=R[i];
low=1;high=i-1;
while(low<=high)
{
m=(low+hige)/2
if(R[0]elselow=m+1;//插入点在后半区
}
for(j=i-1;j>=high+1;--j)
R[j+1]=R[j];
R[high+1]=R[0];
}
}
(3)希尔排序
ShellSort(RecordnodeR[],intn)
{
//用希尔排序法对一个记录r[]排序
inti,j,d;
intbool;
intx;
d=n;
do{d=[d/2];
bool=1
for(i=1;i<=L.length-d;i++)
{
j=i+d
if(R[i]>R[j])
{
x=R[i];
R[i]=R[j];
R[j]=x
bool=0
}
}while(d>1)
}
}
(4)冒泡排序
voidBubbleSort(SeqListR)
{
//R(1…n)是待排序的文件,采用自上向下扫描,对R做冒泡排序
inti,j;
Booleanexchange;//交换标志
for(i=1;i{
//最多做n-1趟排序
exchange=FALSE;//本趟排序开始前,交换标志应为假
for(j=n-1;j<=i;j--)//对当前无序区R[i…n]自下向上扫描
if(R[j+1].key{
R[0]=R[j+1];//R[0]不是哨兵,仅做暂存单元
R[j+1]=R[j];
R[j]=R[0];
exchange=TRUE;//发生了交换,故将交换标志置为真
}
if(!
exchange)//本趟排序未发生交换,提前终止算法
return;
}
}
(5)快速排序
voidQuickSort(SeqListR,intlow,inthigh)
{
//对R[low…high]快速排序
intpivotpos;//划分后的基准记录的位置
if(low{//仅当区间长度大于1时才须排序
pivotpos=Partition(R,low,high);//对R[low…high]做划分
QuickSort(R,low,pivotpos-1);//对做区间递归排序
QuickSort(R,pivotpos+1,high);//对右区间递归排序
}
}//QuickSort
intPartition(SeqListR,inti,intj)
{
//调用Partition(R,low.high)时,对R[low…high]做划分,返回基准记录的位置
ReceTypepivot=R[i];//用区间的第1个记录作为基准
while(i{//从区间两端交替向中间扫描,直至i=j为止
while(i=pivot.key)//pivot相当于在位置i上
j--;//从右向左扫描,查找第1个关键字小于pivot.key的记录R[j]
if(iR[i++]=R[j];//相当于交换R[i]和R[j],交换后i指针加1
while(ii++;//从左向右扫描,查找第1个关键字大于pivot.key的记录R[i]
if(ipivot.key
R[j--]=R[i];//相当于交换R[i]和R[j],交换后j指针减1
}
R[i]=pivot;//基准记录已被最后定位
returni;
}//partition
3.函数的调用关系图
4.调试分析
调试中遇到的问题及对问题的解决方法
(1)对随机函数的应用中怎样保证其每次产生随机序列的不重复
解决办法:
利用系统时间,调用time函数
(2)排序中移动次数和比较次数的确定
解决办法:
动态跟踪函数循环,并分析
算法的时间复杂度和空间复杂度
排序方法
平均时间
最坏情况
最好情况
辅助时间
稳定性
直接插入排序
O(n2)
O(n2)
O(n)
O
(1)
稳定
直接选择排序
O(n2)
O(n2)
O(n2)
O
(1)
稳定
冒泡排序
O(n2)
O(n2)
O(n)
O
(1)
稳定
快速排序
O(nlog2n)
O(n2)
O(nlog2n)
O(log2)
不稳定
堆排序
O(nlog2n)
O(nlog2n)
O(nlog2n)
O
(1)
不稳定
归并排序
O(nlog2n)
O(nlog2n)
O(nlog2n)
O(n)
稳定
5.测试结果
6.源程序(带注释)
随机函数生成函数:
voidrandoming(inta[])
{
srand((int)time(0));
for(intx=0;x<1000;x++)
printf("%d\t",rand()%100);
输出函数:
voidoutput(intn,inta[],intct,intmt)//内部排序中调用的输出函数
{
inti;
printf("\n排序结果:
");
for(i=0;iprintf("%d\t",a[i]);//输出各排序完成的数组
printf("\n比较次数:
%d\n",ct);//输出各排序比较次数
printf("移动次数:
%d\n\n",mt);//输出各排序移动次数
}
数据录入方式选择:
if(j==1)randoming(A);//产生一组随机数据
if(j==2)//产生一组递增序列
for(m=0;m<=N;m++)
A[m]=m;
if(j==3)//产生一组递减序列
for(m=0;m<=N;m++)
A[m]=N-m+1;
if(j==4)//由用户自己输入数据序列,设这组数据中不含0,以0作为结束
{
printf("PleaseInputthesortdata:
(endof0)\n");
A[0]=1;
m=0;
while((m{
m++;
scanf("%d",&(A[m]));
}
//m--;
}
//输出排序前的序列
printf("Thesourcedata:
\n");
for(i=1;i<=m;i++)
printf("%d\t",A[i]);
printf("\t\t选择一种排序方法:
\n");
printf("\t\t1----InsertSort\n");
printf("\t\t2----BubbleSort\n");
printf("\t\t3----SelectSort\n");
printf("\t\t4----QuickSort\n");
printf("\t\t5----shell_sort\n");
//插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序
scanf("%d",&j);
if(j==1)insertion_sort(m,A);//直接插入排序
if(j==2)bubble_sort(m,A);//冒泡排序
if(j==3)selection_sort(m,A);//直接选择排序
if(j==4)quick_sort(m,A);//快速排序,0,0
if(j==5)shell_sort(m,A);//希尔排序
}
总结
通过本次课程设计,我对内部各种算法以及它的递归与非递归应用,查找任意数有了更深刻的了解,巩固了课堂学习的关于各种算法的知识。
当遇到一个算法问题时,首先要知道自己以前有没有处理过这种问题,如果见过,那么你一般会做出来;如果没见过,那么考虑以下问题:
1、问题是否是建立在某种已知的熟悉的数据结构(例如,选择,冒泡,堆等)上?
如果不是,则要自己设计数据结构。
2、问题所要求编写的算法属于以下哪种类型?
(建立数据结构,修改数据结构,遍历,查找,排序……)
3、分析问题所要求编写的算法的数学性质,是否具备递归特征?
(对于递归程序设计,只要设计出合理的参数表以及递归结束的条件,则基本上大功告成。
)
4、确认你的思路可行,然后开始编写程序,在编写代码的过程中,尽可能把各种问题考虑的详细,周密,程序应该具有良好的结构,并且在关键的地方配有注释。
更重要的是对VC++有了更深的认识,初步学会了运用MFC,基本掌握了简单的连接。
同时在课程设计的过程中也深深地感到了自己专业知识的匮乏,动手能力极差。
在今后的学习中加强动手能力的培养,加强实践!
参考文献
[1]严蔚敏,吴伟民.《数据结构(C语言版)》.清华大学出版社.
[2]严蔚敏,吴伟民.《数据结构题集(C语言版)》.清华大学出版社.
[3]《DATASTRUCTUREWITHC++》.WilliamFord,WilliamTopp.清华大学出版社(影印版).
[4]谭浩强.《c语言程序设计》.清华大学出版社.
致谢
经过这三周的课设,我们获得了许多在课堂上听课而不能获得的知识,首先我们要感谢学校给我们安排的这次的算法与数据结构程序设计实习,然后我要感谢老师们对我们热心的指导和帮助,是她们教会了我们怎样解决问题的方法,这样我们的程序设计才会更加顺利地进行,并且充分掌握了设计程序的方法。
我们还要感谢许多同学的帮助,他们的帮助对于我们来说也是必不可少的。
总之,是有了他们的帮助,我们才能顺利地完成软件设计,在这里我们要向他们说一句:
谢谢,非常感谢!
你们辛苦了!
附件Ⅰ任务一源程序代码
#include
#include
usingnamespacestd;
#defineint_max10000
#defineinf9999
#definemax20
//…………………………………………邻接矩阵定义……………………
typedefstructArcCell
{
intadj;
char*info;
}ArcCell,AdjMatrix[max][max];
typedefstruct
{
charvexs[max];
AdjMatrixarcs;
intvexnum,arcnum;
}MGraph_L;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
intlocalvex(MGraph_LG,charv)//返回V的位置
{
inti=0;
while(G.vexs[i]!
=v)
++i;
returni;
}
intcreatMGraph_L(MGraph_L&G)//创建图用邻接矩阵表示
{
charv1,v2;
inti,j,w;
cout<<"…………创建无向图…………"<(46)不包括“()”"<cin>>G.vexnum>>G.arcnum;
for(i=0;i!
=G.vexnum;++i)
{
cout<<"输入顶点"<
cin>>G.vexs[i];
}
for(i=0;i!
=G.vexnum;++i)
for(j=0;j!
=G.vexnum;++j)
{
G.arcs[i][j].adj=int_max;
G.arcs[i][j].info=NULL;
}
for(intk=0;k!
=G.arcnum;++k)
{
cout<<"输入一条边依附的顶点和权:
(ab3)不包括“()”"< cin>>v1>>v2>>w;//输入一条边依附的两点及权值
i=localvex(G,v1);//确定顶点V1和V2在图中的位置
j=localvex(G,v2);
G.arcs[i][j].adj=w;
G.arcs[j][i].adj=w;
}
cout<<"图G邻接矩阵创建成功!
"<returnG.vexnum;
}
voidljjzprint(MGraph_LG)//邻接矩阵的输出
{
inti,j;
for(i=0;i!
=G.vexnum;++i)
{
for(j=0;j!
=G.vexnum;++j)
cout< cout<}
}
intvisited[max];//访问标记
intwe;
typedefstructarcnode//弧结点
{
intadjvex;//该弧指向的顶点的位置
structarcnode*nextarc;//弧尾相同的下一条弧
char*info;//该弧信息
}arcnode;
typedefstructvnode//邻接链表顶点头接点
{
chardata;//结点信息
arcnode*firstarc;//指向第一条依附该结点的弧的指针
}vnode,adjlist;
typedefstruct//图的定义
{
adjlistvertices[max];
intvexnum,arcnum;
intkind;
}algraph;
//…………………………………………队列定义……………………
typedefstructqnode
{
intdata;
structqnode*next;
}qnode,*queueptr;
typedefstruct
{
queueptrfront;
queueptrrear;
}linkqueue;
//………………………………………………………………………
typedefstructacr
{
intpre;//弧的一结点
intbak;//弧另一结点
intweight;//弧的权
}edg;
intcreatadj(algraph&gra,MGraph_LG)//用邻接表存储图
{
inti=0,j=0;
arcnode*arc,*tem,*p;
for(i=0;i!
=G.vexnum;++i)
{
gra.vertices[i].data=G.vexs[i];
gra.vertices[i].firstarc=NULL;
}
for(i=0;i!
=G.vexnum;++i)
{
for(j=0;j!
=G.vexnum;++j)
{
if(gra.vertices[i].firstarc==NULL)
{
if(G.arcs[i][j].adj!
=int_max&&j!
=G.vexnum)
{
arc=(arcnode*)malloc(sizeof(arcnode));
arc->adjvex=j;
gra.vertices[i].firstarc=arc;
arc->nextarc=NULL;
p=arc;
++j;
while(G.arcs[i][j].adj!
=int_max&&j!
=G.vexnum)
{
tem=(arcnode*)malloc(sizeof(arcnode));
tem->adjvex=j;
gra.vertices[i].firstarc=tem;
tem->nextarc=arc;
arc=tem;
++j;
}
--j;
}
}
else
{
if(G.arcs[i][j].adj!
=int_max&&j!
=G.vexnum)
{
arc=(arcnode*)malloc(sizeof(arcnode));
arc->adjvex=j;
p->nextarc=arc;
arc->nextarc=NULL;
p=arc;
}
}
}
}
gra.vexnum=G.vexnum;
gra.arcnum=G.arcnum;
cout<<"图G邻接表创建成功!
"<return1;
}
voidadjprint(algraphgra)//邻接表输出
{
inti;
for(i=0;i!
=gra.vexnum;++i)
{
arcnode*p;
cout<
p=gra.vertices[i].firstarc;
while(p!
=NULL)
{
cout<adjvex;
p=p->nextarc;
}
cout<}
}
intfirstadjvex(algraphgra,vnodev)//返回依附顶点V的第一个点
//即以V为尾的第一个结点
{
if(v.firstarc!
=NULL)
returnv.firstarc->adjvex;
}
intnextadjvex(algraphgra,vnodev,intw)//返回依附顶点V的相对于W的下一个顶点
{
arcnode*p;
p=v.firstarc;
while(p!
=NULL&&p->adjvex!
=w)
{
p=p->nextarc;
}
if(p->adjvex==w&&p->nextarc!
=NULL)
{
p=p->nextarc;
returnp->adjvex;
}
if(p->adjvex==w&&p->nextarc==NULL)
return-10;
}
intinitqueue(linkqueue&q)//初始化队列
{
q.rear=(queueptr)malloc(sizeof(qnode));
q.front=q.rear;
if(!
q.front)
return0;
q.front->next=NULL;
return1;
}
intenqueue(linkqueue&q,inte)//入队
{
queueptrp;
p=(queueptr)malloc(sizeof(qnode));
if(!
p)
return0;
p->data=e;
p->next=NULL;
q.rear->next=p;
q.rear=p;
return1;
}
intdequeue(linkqueue&q,int&e)//出队
{
queueptrp;
if(q.front==q.rear)
return0;
p=q.front->next;
e=p->data;
q.front->next=p->next;
if(q.rear==p)
q.rear=q.front;
free(p);
return1;
}
intqueueempty(linkqueueq)//判断队为空
{
if(q.front==q.rear)return1;
ret