数据结构各种排序算法的时间性能.doc
《数据结构各种排序算法的时间性能.doc》由会员分享,可在线阅读,更多相关《数据结构各种排序算法的时间性能.doc(19页珍藏版)》请在冰豆网上搜索。
HUNANUNIVERSITY
课程实习报告
题目:
排序算法的时间性能
学生姓名
学生学号
专业班级
指导老师 李晓鸿
完成日期
设计一组实验来比较下列排序算法的时间性能
快速排序、堆排序、希尔排序、冒泡排序、归并排序(其他排序也可以作为比较的对象)
要求
(1)时间性能包括平均时间性能、最好情况下的时间性能、最差情况下的时间性能等。
(2)实验数据应具有说服力,包括:
数据要有一定的规模(如元素个数从100到10000);数据的初始特性类型要多,因而需要具有随机性;实验数据的组数要多,即同一规模的数组要多选几种不同类型的数据来实验。
实验结果要能以清晰的形式给出,如图、表等。
(3)算法所用时间必须是机器时间,也可以包括比较和交换元素的次数。
(4)实验分析及其结果要能以清晰的方式来描述,如数学公式或图表等。
(5)要给出实验的方案及其分析。
说明
本题重点在以下几个方面:
理解和掌握以实验方式比较算法性能的方法;掌握测试实验方案的设计;理解并实现测试数据的产生方法;掌握实验数据的分析和结论提炼;实验结果汇报等。
一、需求分析
(1)输入的形式和输入值的范围:
本程序要求实现各种算法的时间性能的比较,由于需要比较的数目较大,不能手动输入,于是采用系统生成随机数。
用户输入随机数的个数n,然后调用随机事件函数产生n个随机数,对这些随机数进行排序。
于是数据为整数
(2)输出的形式:
输出在各种数目的随机数下,各种排序算法所用的时间和比较次数。
(3)程序所能达到的功能:
该程序可以根据用户的输入而产生相应的随机数,然后对随机数进行各种排序,根据排序进行时间和次数的比较。
(4)测试数据:
略
二、概要设计
1.抽象数据类型
ADTList
数据对象D={ai|ai∈ElemSet,i=1,2,...,n,n≥0}
数据关系R1={|ai-1,ai∈D,i=2,...,n}
基本操作virtualvoidclear()=0;
boolinsert(constElem&)=0;
boolappend(constElem&)=0;
lboolremove(Elem&)=0;
voidsetStart()=0;
voidsetEnd()=0;
voidprev()=0;
voidnext()=0;
intleftLength()const=0;
intrightLength()const=0;
boolsetPos(intpos)=0;
boolgetValue(Elem&)const=0;
voidprint()const=0;
2.程序的流程
(1)输入模块:
输入要排序的数的数量n
(2)处理模块:
系统产生n个随机数,对随机数进行排序
(3)输出模块:
将排序的结果输出
3.算法的基本思想
1、随机数的产生:
利用srand()产生随机数。
2、快速排序:
选定一记录R,将所有其他记录关键字k’与记录R的关键字k比较,若k’k则将记录换至R之后,继续对R前后两部分记录进行快速排序,直至排序范围为1
3、插入排序:
逐个处理待排序的记录,每个新记录与前面已排序的子序列进行比较,将它插入到子序列中正确的位置
4、冒泡排序:
比较并交换相邻的元素对,直到所有元素都被放到正确的地方为止。
5、归并排序:
将两个或者多个有序表归并成一个有序表
6、堆排序:
首先将数组转化为一个满足堆定义的序列,然后将堆顶的最大元素取出,再将剩下的数排成堆,再取堆顶数值,…。
如此下去,直到堆为空。
到最后结束时,就排出了一个由小到大排列的数组。
三、详细设计
(1)产生随机数:
直接调用函数srand(),以时间作为随机种子进行选择,并把随机数装入数组中
unsignedlongint*Sort:
:
setRan(unsignedlongintnum){
unsignedlongint*ra;
ra=(unsignedlongint*)malloc(num*sizeof(unsignedlongint));
srand(time(NULL));
for(unsignedlongintm=0;m ra[m]=rand();
}
cout< returnra;
}
(2)快速排序:
要实现快速排序首先选择一个轴值,这里选取数组第一个为轴值。
定义两个标识low,high。
high标识最后一个元素的位置,从后向前,将关键字与轴值比较,直至遇到小于轴值的关键字,前移,low标识在第二个元素的位置,从前向后,将关键字与轴值比较,直至遇到大于轴值的关键字,后移。
当low,high相遇后第一趟排序结束。
调整数列,轴值左边的为比轴值小的,右边为比轴值大的。
对轴值左边(即low到pivotkey-1的数)和右边的子列(pivotkey+1到high的数)分别进行上述递归快速排序,直到范围为1结束。
intpartition(inta[],intlow,inthigh){//快速排序中的一趟
intpivotkey;//作为枢轴来使用
pivotkey=a[low];
while(lowwhile(low=pivotkey)
--high;
a[low]=a[high];
while(low++low;
a[high]=a[low];
}
a[low]=pivotkey;
returnlow;
}
voidqsort(inta[],intlow,inthigh){//快速排序的递归形式
intpivotloc;
if(lowpivotloc=partition(a,low,high);//一趟排序结果的调用
qsort(a,low,pivotloc-1);
qsort(a,pivotloc+1,high);
}
}
(3)插入排序:
插入排序的思想是将一组无序的元素分别插入一个已经有序的的数组里,并保证插入后的数组也是有序的。
当所有无序组的元素都插入完毕时,一个有序数组构造完成。
数组n[1…r]为初始的一个无序数组(为了直观起见,我们这里设定数组从1开始,而不是0),则n[1]默认为只有一个元素的有序数组,n[2]插入只有n[1]构成的有序数组中,则此时有序数组的元素数量变为2。
以此类推,到第i个元素时,前i-1个元素已经是有序的,此时只需将第i个元素插入到有序数组中并使之保持有序。
如此直至最后一个元素插入完毕,整个插入排序完成。
voidSort:
:
insertSort(unsignedlongint*s){
this->setNum();
LARGE_INTEGERFreg;
LARGE_INTEGERCount1,Count2;
QueryPerformanceFrequency(&Freg);
QueryPerformanceCounter(&Count1);//获取时间Count1
doubled;
inttemp,j;
for(unsignedlonginti=0;igetRanNum();i++)
{
j=i;
temp=s[i];
while(j>=1&&temp
{s[j]=s[j-1];
j--;
this->SortNum++;
}
if(j>1)
this->SortNum++;
s[j]=temp;
}
QueryPerformanceCounter(&Count2);//获取时间Count2
d=(double)(Count2.QuadPart-Count1.QuadPart)/(double)Freg.QuadPart*1000.0;//计算时间差,d的单位为ms.
cout<<"插入排序算法对"<RanNum<<"个随机数排序时间为为"< cout<<"插入排序算法对"<RanNum<<"个随机数交换次数为"<SortNum<<"次。
"<
}
(4)冒泡排序(bubblesort):
将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。
根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:
凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。
如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
从无序区底部向上依次比较相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。
即依次比较(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);对于每对气泡(R[j+1],R[j]),若R[j+1].key第一趟扫描完毕时,"最轻"的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置R[1]上。
扫描R[2..n]。
扫描完毕时,"次轻"的气泡飘浮到R[2]的位置上……最后,经过n-1 趟扫描可得到有序区R[1..n]
voidSort:
:
bubbleSort(unsignedlongint*s){
this->setNum();
LARGE_INTEGERFreg;
LARGE_INTEGERCount1,Count2;
QueryPerformanceFrequency(&Freg);
QueryPerformanceCounter(&Count1);//获取时间Count1
doubled;
unsignedlonginttemp;
for(unsignedlonginti=0;i<(this->RanNum);i++){
for(intj=i+1;j<(this->RanNum);j++){
if(s[i]>s[j]){
temp=s[i];
s[i]=