《排序问题求解》实验报告Word格式文档下载.docx
- 文档编号:19143425
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:17
- 大小:70.04KB
《排序问题求解》实验报告Word格式文档下载.docx
《《排序问题求解》实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《《排序问题求解》实验报告Word格式文档下载.docx(17页珍藏版)》请在冰豆网上搜索。
Q
J=2
6
A(i+l)=A(i);
Cs
1)
7
i=i-l:
G
£
(勺-1)
;
=2
8
repeat
■
9
A(i+1)=item
C7
10
EndInsertionSort
首先给出快速排序(InsertionSort)过程中,每一条指令的执行时间及执行次数。
对j=2,3,...,n/n=length[A],设勺为while循坏所做的测试次数。
半for或while循坏以通常方式退出(即,因为循环头部的测试条件不满足而退出)时,测试要比循环体实执行[次。
该算法总的运行时间是每一条语句执行时间总和。
如果执行一条语句需要C,步,又共执行了n次这条语句,那么它在总运行时间中占Cru为计算总运行时间T[n],对每一对cost与times之积求和,得:
nn
+5》(勺-1)+。
6》(勺-1)+C7(n-1)j=2;
在Insertionsort中,如果输入数组已经是排好序的话.就会出现最佳情况。
对j=2,3“n中的每一个值,当j取其初始值jJ时,都有A[j]<
iterm于是,对j=2,3,…,m有堺1,敲佳运行时间为:
r(n)=qn+c2(n一1)+c3(n-1)+c4(n~1)+c7(n-1)
=(C]+C2+C3+C4+€7)11—(C?
+C3+C4+C7)
这一运行时间可以表示为an+b,常量a和b依赖于语句的代价5因此它是n的一个线性函数。
如果输入数组是按照逆序排序的(即,是按递降顺序排序的),那么就会出项瑕坏的情况。
我们必须将每个元素A[j]9整个己排序的了数组A[仁j・1]中的每•个元素进行比较,因而,对j=2,3,...,n,有tj=j。
在最坏情况下,hisertionSort的运行时间为:
T(n)=C1n+°
(n7+c3(n-!
)+c4(呼1-i)+c5(忖)+“(忖)
+C7(n-1)
C4C5C6
+c2+c3+7---t+
这一最坏情况运行时间可以表示为a〃2+bn+c,常最b和c依赖于语句的代价Q;
因此这是一个关于n的二次函数。
因此直接插入排序算法,在最佳情况卜的时间复杂度是0(n),在最坏情况下的时间复杂度为0(?
l2)。
2.快速排丿字
-趟快速排序算法:
intPartition(intA[n]#intlow,inthigh)
A[0]=A[low];
〃用数组的第•个记录做枢轴记录
privotkey=A[low];
while(low<
high)
〃枢轴记录关键字
〃从表的两端交替地向中间tn描
while(low<
high&
&
A[high]>
=privotkey)-high;
A[low]=A[high];
〃将比枢轴记录小的记录移到低端
A[low]<
=pivotkey)++low;
A[high]=A[low);
〃将比枢轴记录人的记录移到高端
i
A[low]=A[0];
returnlow;
〃枢轴记录到位
〃返回枢轴位置
}
快速排序算法:
voidQuicksort(intA[],intlow,inthigh)〃对数组中记录进行快速排序
{
if(low<
high)〃长度人于
pivotioc=Parition(A,low,high);
〃将A[]中数据•分为QuickSort(A,low,pivotloc-1);
QuickSort(A,pivotloc+l,high);
卜面我们来分析快速排序的平均时间性能。
假设T(n)为对n个记录A[l..n]进行快速排序所需时间,则由算法QuickSort町见:
T(n)=Tmss(n)+T(k_l)+T(n_k)
其中,Tp&
n)为对n个记录进行一趟快速排序Partition(A,1,n)所需的时间,从一趟快速排序算法町见,其利记录数n成正比,可以用cn表示(c为某个常数);
T(k-l)和T(n~k)分别为对A[l..k_l]和A[k+1..n]中记录进行快速排序QuickSort(A,1,k_l)和Quicksort(A,k+l,n)所需时间。
假设待排序列中记录是随机排列的,则在一趟排序之后,k取1至n之间任何一值的槪率和同,快速排序所需时仙的平均值则为
假定Tavs(l)<
b(b为某个常量),则
Tavg(n)=^^Tavg(n-1)+^-^-c
11
Tavg(l)+2(n+l)(-+j++
(bb\
V匕+2cJ(n+l)In(n+1)n>
2
快速排序的平均时间为Tavg(n)=kiiliin,其中n为待排序序列中记录的个数,k为某个常数。
通常,快速排序被认为是,在所有同数屋级(O(nlogn))的排序方法中,其平均性能最好。
但是,若初始记录序列按关键字有序或基本有序时,快速排序将蜕化为起泡排序,其时间复杂度为0(n2)o
三、程序流程图
1.直接插入排序流程图
2.一趟快速排斥流程图
四、实验分析
1.实验环境
1)软件平台
操作系统:
Windows2003EnterpriseEdition32位SP2(DirectX9.0c)编译软件:
MicrosoftVisualStudio2008
2)硬件平台:
电脑型号•:
X86兼容台式电脑
处理器:
AMDAthlonf速龙)64X2双核5200+内存:
2GB(金邦DDR2800MHz)
2.实验结果记录
1)程序的执行
首先由函数datagenetaref)^成20000个在区间[1,100000]上的随机整数,并调用函数WriteFile()将这些数输出到外部文件data.txt中。
然后分别调用函数ReadFilef)从data.txt中读取数据,分别进行II接插入排序和快速排序,并分别计算和记录其运行时间。
最后,调用惭数WriteFileO将直接插入排序的结果写入resultslS.txt,快速排序的结果写入resultsQS.txto
2)实验结果
表2记录了对于相同的数据,分别运用直接插入排序算法和快速排序算法,cup的运行时间。
数据分别是20000^81900个在区间[1,10C000]上的随机整数。
表2:
直接插入排序和快速排序的运行时间对比表
记录数目一
直接插入排序
快速排序
20000
0.625000
0.000000
30000
1.453000
40000
2.625000
50000
4.109000
60000
6.047000
0.016000
70000
8.250000
80000
10.750000
81000
11.062000
82000
11.250000
0.015000
接表2:
1'
〔接插入排序和快速排序运行时间对比
83000
11.672000
84000
12.093000
84500
12.156000
0.031000
84800
11.937000
84900
12.078000
3)实验结果分析
由衣2绘制图衣:
直接插入排序和快速排序的运行时间对比
200300400500600700800810820830840845848849
Y-直接插入排序
-■-快速排序
记录个数(单位:
百)
运行时间(单位••秒)
如图表所示:
在平均情况2快速排序的效率高于直接插入排序,直接插入排序的效率随元素个数的增加而降低,而快速排序的运行效率的变化很小。
五、实验总结
通过本次实验,我熟悉了直接插入排序和快速排序,锻炼了编码能力。
书本上只是基础知识,在解决实际问题的过程中,我才加深对知识点的认识。
我们町以很形象地描述算法,却不一定可以编程语言表达出来,实现我们想要的功能。
此次实验,用C语肓实现了直接插入排序和快速排序算法,并进行运行时间的比较。
但是,很明显存在不少的缺陷。
首先,待排序的数组是随机生成的整数,只能进行平均情况卜•的运行效率分析,无法在最佳情况下和最坏情况下进行算法分析。
而且,随机数不能保证是不重复的。
其次,程序是在VS2008运行的,元素个数不可以超过85000个。
六、代码
(C语言)
#inckide<
stdio.h>
#include<
conio.h>
stdlib.h>
time.h>
#defineNumS20000
voiddatagenetare(intnum[]Jntn);
〃产生随机数,保:
存到数num
voidWriteFile(intnumfl.charname[]Jntn);
//输出数组num到名为name的文件
voidReadFilefintnumfj^charname[],int<
<
为name文件中的数据,保1?
到数组num
voidQuickSortfintair[],intn);
〃将数组arr[]中数据快速排序voidlnsertionSort(intarr[]Jntn);
〃将数纟Jdir[]中数据了[接插入押庁
main()
intnum[NumS]muml[NumS]』um2[NumS];
doubletimeQS=0,timelS=0;
FILE*fp=NULL;
clock_tstart_time2,end_timehstart_time2,end_time2;
printf("
Create%drandomnumbersfrom1tolOOOOOXn'
^NumS);
datagenetare(num,NumS);
〃产牛随机数,保存到数细num
WriteFilelnum/'
data.txt'
〃输出数纽到data.txt文件
〃直接插入排序的分析
ReadFile(numl,"
data.txt"
NumS);
〃i卖取data.txt中的数据,保存到数纟Hnumlprintf(H\nlnsertionSortStart
start_timel=clock();
〃开始计时
InsertionSorttnumXNumS);
//1芷接插入林序数组numl中的数据
end_timel=clock();
〃结束计时
timelS=(double)(end_timel-start_tiniel)/CLOCKS_PER_SEC;
printff'
TheTime-comsuptioninInsertionSortis%lfseconds!
\n\rV:
timelS);
〃输出运行时间
WriteFilelnuml/'
resultslS.txt'
//排序后的数据输出到resultQS.txt
〃输出运行时间timelS到resultslS.txt
if(fp=fopen(,,resultslS.txt"
/,a,'
))〃打开resultslS.txt
fprintf(fp/"
%s%lf%s,l/,,\nTheTime-comsuptioninInsertionSortis'
\timelSJ1seconds\nH);
fclose(fp);
elseprintf("
\nCannotopenresultslS.txt!
\n"
);
exit(l);
〃异常退出
〃快速排序的分析
ReadFile(num2/data.txt"
〃读取data.txt"
I1的数据,保1?
到数纟:
num2[]printff'
QuickSortStart..…\n"
);
start_time2=clock();
QuickSort(num2,NumS);
〃快速MM#数纽num屮的数据end_time2=clock();
timeQS=(double)(end_time2-start_time2)/CLOCKS_PER_SEC;
printff'
TheTime-comsuptioninQuicksortis%lfseconds:
\n'
\timeQS);
〃输出运行时间WriteFile(num2,"
resultsQS.txt"
//输出运行时间timeQS到resultsQS.txt
if(fp=fopen("
/"
a"
))〃打开resultsQS.txt
fprintf(fp/,%s%lf%s,7'
\nTheTime-comsuptioninQuicksortis"
timeQS,"
seconds\n"
else
\nCannotopenresultsQS.txt!
return0;
〃生成n个随机数,并将其保存到num[]
voiddatagenetare(intnum[]Jntn)
inti,w=0,t=0;
srand((unsigned)time(O));
〃srand()种了发生器函数,使用系统时间来初始化。
rand()随机数生成器函数
for(i=0;
i<
n;
i++)〃产生n个1到100000之间的随机数num[i]=rand()%99999+l;
printfCXn'
*);
〃将数组中的数据输出到文件
voidWriteFile(intnum[],charname[],intn)
ULt*fp=fopen(name,"
w"
inti=0;
if(fp==NULL)
for(;
i++)
fprintf(fp,"
%6d"
num[i]);
//输出生成的随机数到data.txt
if((i+l)%40==0||i==n-l)〃每输岀个数,换一行
fprintf(fpAn"
}fclose(fp);
〃将文件中的数据输入到数组
voidReadFile(intnum[],charname[],intn)
inti;
FILE*fp=fopen(name/"
r"
ll\『开名为name的文件
〃异'
常退LB
fscanf(fp;
'
&
num[i]);
〃读出文件中数据到数组
fclose(fp);
〃快速排序的实现,从左向右递增排序
voidQuickSort(intarr[]zintn)
intL=0;
intR=n-1;
intt=arr[L];
〃区间的第一个数作为基准
if(n<
=l)〃数组中存在个或个数据时,函数返回
return;
〃将数据分成两个区间
while(L<
R){〃区仙内至少存在一个元素的情况
R&
tv=arr[R])R“;
〃从右向左搜索,直到第一个小于t的数ar^R]arr[L]=arr[R];
arr[L]<
=t)L++;
〃从左向右搜索,找到第一个人于t的数arr[L]arr[R]=arr[L];
arr[LJ=t;
QuickSortfarr,L);
//对左区间递归排序
QuickSortfarr+L+Xn-L-l);
//对右区间递i丿I扌旧?
〃直接插入排序的实现,从左向右递增排序
voidInsertionSortfintarr[],intn)
inti=0,temp=0j=0;
=l)
for(i=l;
++i)
temp=arr[i];
//temp记录要插入的数据arr[i]
j=i;
〃要插入的数据的位豐
j>
0&
arr[j-l]>
temp;
-j)〃将a[i]插入到己排序的arr[O]~aiT[i-l]中{
arr[j]=arr[j-l];
〃比temp大的数据依次后移
}arrD]=temp;
〃找到第一个不人于于temp的数据,在j处插入arr[i]
(C++语言)
#include<
iostream>
ctime>
//include<
cstdlib>
fstream>
#inelude<
string>
usingnamespacestd;
constintNumS=20000;
//产生随机数,保存到数组num
voidWriteFile(intnum[],charname[],intn);
〃输出数组num到data.txt文件
voidReadFilefintnum[]zcharname[]);
//i5-取名为name文件中的数拯,保存到数组numvoidQuickSortfintarr[],intn);
//^数组air[]中数据快速排序
voidInsertionSortfintarr[],intn);
〃将数fllarr[],|,数据M接插入排序
intmain()
intnum[NumS],numl[NumS]/num2[NuinS];
clock_tstart_time2,end_time2,start_time2,end_time2;
doubletimeQS=0/timelS=0;
cout«
"
Create"
«
NumS«
randomnumbersfromlto100000"
endl;
〃产生随机数,保心到数纟Hnum
WriteFile(num/'
data.txt"
〃输出数组到data.txt文件
coutprecision(6);
//设置浮点数的显示精度coutsetf(ios_base:
:
showpoint);
〃输出木丿€的
ReadFile(numl/data.txt取data.txt【|i的数据■保存到数纽numl
\nlnsertionSortStart…・\rT;
lnsertionSort(numl,NumS);
〃冼接插入排序数fltnuml中的数据
〃结束计时timelS=(double)(end_timel-start_timel)/CLOCKS_PER-SEC;
HTheTime-comsuptioninInsertionSortis,,«
timelS«
seconds!
\n\nlf;
〃输出运彳亍时间
WriteFilelnuml/resultslS.txt^NumS);
〃排序k;
的数据输出到resultQS.txt
〃输出运行时间timelSflJresultslS.txt
ofstreamocout;
ocout.open('
Josiiapp);
if(ocoutgood())〃打开resultslS.txt
ocout«
n\nTheTime-comsuptioninInsertionSortisH«
seconds、"
ocoutclose();
\nCannotopenresultslS.txt!
\nH;
ReadFile(num2,"
〃i卖取data.txt中的数据,保存到数Slnum2[]
QuickSortStart••…\n"
;
start_time2=clock();
〃快速排序数flnum11*的数据
end_time2=clock();
〃结束计时timeQS=(double)(end_time2・start_time2)/CLOCKS_PER_SEC;
TheTime-comsuptioninQuicksortis,,«
timeQS«
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 排序问题求解 排序 问题 求解 实验 报告