实验一算法的时间复杂度.docx

上传人:b****4 文档编号:27166583 上传时间:2023-06-27 格式:DOCX 页数:15 大小:98.76KB
下载 相关 举报
实验一算法的时间复杂度.docx_第1页
第1页 / 共15页
实验一算法的时间复杂度.docx_第2页
第2页 / 共15页
实验一算法的时间复杂度.docx_第3页
第3页 / 共15页
实验一算法的时间复杂度.docx_第4页
第4页 / 共15页
实验一算法的时间复杂度.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

实验一算法的时间复杂度.docx

《实验一算法的时间复杂度.docx》由会员分享,可在线阅读,更多相关《实验一算法的时间复杂度.docx(15页珍藏版)》请在冰豆网上搜索。

实验一算法的时间复杂度.docx

实验一算法的时间复杂度

实验一算法的时间复杂度

一、实验目的与要求

熟悉C/C++语言的集成开发环境;

通过本实验加深对算法分析基础知识的理解。

二、实验内容:

掌握算法分析的基本方法,并结合具体的问题深入认识算法的时间复杂度分析。

三、实验题

定义一个足够大的整型数组,并分别用起泡排序、简单选择排序、快速排序和归并排序对数组中的数据进行排序(按从小到大的顺序排序),记录每种算法的实际耗时,并结合数据结构中的知识对算法的时间复杂度分析进行说明。

实验数据分两种情况:

1、数组中的数据随机生成;

2、数组中的数据已经是非递减有序。

四、实验步骤

理解算法思想和问题要求;

编程实现题目要求;

上机输入和调试自己所编的程序;

验证分析实验结果;

整理出实验报告。

五、实验程序

#include

#include

usingnamespacestd;

constintn=5000;//可根据需要更改数组大小

classSort

{

public:

voidRadom();//生成一个随机数数组

voidOrder();//生成一个非递减数组

voidBubbleSort(intr[],intn);//冒泡排序

voidSelectSort(intr[],intn);//简单选择排序

intPartition(intr[],intfirst,intend);//快速排序一次划分算法

voidQuickSort(intr[],intfirst,intend);//快速排序

voidMerge(intr[],intr1[],ints,intm,intt);//一次归并排序

voidMergeSort(intr[],intr1[],ints,intt);//归并排序

inta[n];//存放随机数的数组

inta1[n];//存放非递减数据的数组

intexchange;//冒泡排序中记载每次记录交换的位置

intbound;//冒泡排序中记录无序区的最后一个记录

intindex;//简单选择排序中记录在一趟比较过程中关键码最小的记录位置

intpivot;//快速排序中的基准记录

inttemp;//用于排序中的交换

};

//==============================生成随机数组===========================

voidSort:

:

Radom()

{

//srand(unsigned(time(NULL)));

for(inti=0;i

a[i]=rand()%800;//产生随机数

}

//====================================================================

//===============================生成非递减数组=========================

voidSort:

:

Order()

{

for(inti=0;i

a1[i]=i;

}

//====================================================================

//================================冒泡排序=============================

voidSort:

:

BubbleSort(intr[],intn)

{

exchange=n-1;//第一趟冒泡排序的范围是r[0]到r[n]

while(exchange)

{

bound=exchange;

exchange=0;

for(intj=0;j

if(r[j]>r[j+1])

{

temp=r[j+1];

r[j+1]=r[j];

r[j]=temp;

exchange=j;

}

}

}

//====================================================================

//===============================简单选择排序==========================

voidSort:

:

SelectSort(intr[],intn)

{

for(inti=0;i

{

index=i;

for(intj=i+1;j<=n;j++)

{

if(r[j]

index=j;

}

if(index!

=i)

{temp=r[i];

r[i]=r[index];

r[index]=temp;

}

}

}

//====================================================================

//============================快速排序一次划分算法======================

intSort:

:

Partition(intr[],intfirst,intend)

{

inti=first;

intj=end;

while(i

{

while(i

if(i

{

temp=r[i];

r[i]=r[j];

r[j]=temp;//将较小记录换到前面

i++;

}

while(i

if(i

{

temp=r[i];

r[i]=r[j];

r[j]=temp;//将较大记录换到后面

j--;

}

}

returni;//i为轴值记录的最终位置

}

//====================================================================

//==============================快速排序===============================

voidSort:

:

QuickSort(intr[],intfirst,intend)

{

if(first

{

pivot=Partition(r,first,end);//一次划分

QuickSort(r,first,pivot-1);//递归地对左侧子序列进行快速排序

QuickSort(r,pivot+1,end);//递归地对右侧子序列进行快速排序

}

}

//====================================================================

//============================一次归并排序=============================

voidSort:

:

Merge(intr[],intr1[],ints,intm,intt)

{

inti=s;

intj=m+1;

intk=s;

while(i<=m&&j<=t)

{

if(r[i]<=r[j])

r1[k++]=r[i++];

elser1[k++]=r[j++];

}

if(i<=m)while(i<=m)//若第一个子序列没处理完,则进行收尾处理

r1[k++]=r[i++];

elsewhile(j<=t)//若第二个子序列没处理完,则进行收尾处理

r1[k++]=r[j++];

}

//====================================================================

//============================归并排序(递归)============================

voidSort:

:

MergeSort(intr[],intr1[],ints,intt)

{

if(s==t)r1[s]=r[s];

else

{

intm=(s+t)/2;

MergeSort(r,r1,s,m);//归并排序前半个子序列

MergeSort(r,r1,m+1,t);//归并排序前半个子序列

Merge(r1,r,s,m,t);//将两个已排序的子序列归并

}

}

//====================================================================

//===============================主函数================================

intmain()

{

Sorts;

clock_tstart,end;

s.Radom();

start=clock();

s.BubbleSort(s.a,n);

end=clock();

cout<<"随机数组冒泡排序所需时间为:

"<<(double)(end-start)<<"ms"<

s.Radom();

start=clock();

s.SelectSort(s.a,n);

end=clock();

cout<<"随机数组简单选择排序所需时间为:

"<<(double)(end-start)<<"ms"<

s.Radom();

start=clock();

s.QuickSort(s.a,0,n-1);

end=clock();

cout<<"随机数组快速排序所需时间为:

"<<(double)(end-start)<<"ms"<

s.Radom();

intb[n]={0};

start=clock();

s.MergeSort(s.a,b,0,n-1);

end=clock();

cout<<"随机数组归并排序所需时间为:

"<<(double)(end-start)<<"ms"<

cout<

start=clock();

s.BubbleSort(s.a1,n);

end=clock();

cout<<"非递减数组冒泡排序所需时间为:

"<<(double)(end-start)<<"ms"<

s.Radom();

start=clock();

s.SelectSort(s.a1,n);

end=clock();

cout<<"非递减数组简单选择排序所需时间为:

"<<(double)(end-start)<<"ms"<

start=clock();

s.QuickSort(s.a1,0,n-1);

end=clock();

cout<<"非递减数组快速排序所需时间为:

"<<(double)(end-start)<<"ms"<

start=clock();

s.MergeSort(s.a1,b,0,n-1);

end=clock();

cout<<"非递减数组归并排序所需时间为:

"<<(double)(end-start)<<"ms"<

return0;

}

六、实验结果

当n=1000时:

当n=3000时:

当n=5000时:

当n=7000时:

当n=9000时:

当n=11000时:

当n=13000时:

实验结果制表:

随机数组排序所需时间

随机数组

n=1000

n=3000

n=5000

n=7000

n=9000

n=11000

n=13000

冒泡排序

16

62

141

281

453

656

921

简单选择排序

0

31

62

109

203

282

391

快速排序

0

0

0

16

0

0

15

归并排序

0

0

0

0

0

15

0

非递减数组排序所花时间

非递减数组

n=1000

n=3000

n=5000

n=7000

n=9000

n=11000

n=13000

冒泡排序

0

0

0

0

0

0

0

简单选择排序

0

16

46

110

188

282

407

快速排序

0

31

47

94

172

归并排序

0

0

0

0

15

随机数组时间复杂度函数曲线:

非递减数组时间复杂度函数曲线:

七、实验分析

运行环境:

VisualC++6.0CPU:

2.53GHz内存:

1.92GB

系统:

MicrosoftWindowsXPProfessional版本2002

冒泡排序:

在最好情况下,待排序记录序列为正序,算法只执行一趟,进行了n-1次关键码的比较,不需要移动记录,时间复杂度为O(n);

在最坏情况下,待排序记录序列为反序,每趟排序在无序序列中只有一个最大的记录被交换到最终位置,故算法执行n-1趟,第i(1≤i<n)趟排序执行了n-i次关键码的比较和n-i次记录的交换,这样,关键码的比较次数为∑(n-i)=n(n-1)/2,记录的移动次数为3n(n-1)/2,因此,时间复杂度为O(n*n);

在平均情况下,冒泡排序的时间复杂度与最坏情况同数量级。

冒泡排序是一种稳定的排序方法。

简单选择排序:

在选择排序中记录的移动次数较少。

在待排序列为正序时,记录的移动次数最少,为0;第i趟排序需进行n-i次比较,而选择排序需进行n-1趟排序,总比较次数为:

∑(n-1)=n(n-1)/2=O(n*n)

所以,总的时间复杂度为O(n*n),这是简单选择排序最好、最坏、和平均的时间性能。

简单选择排序是一种稳定的排序方法。

快速排序:

在最好情况下,每次划分对一个记录定位后,该记录的左侧子序列与右侧子序列的长度相同。

在具有n个记录的序列中,对一个记录定位要对整个待划分序列扫描一遍,则所需时间为O(n)。

设T(n)是对n个记录的序列进行排序的时间,每次划分后,把待划分区间划分为长度相等的两个子序列,则有:

T(n)≤2T(n/2)+n

≤2(2T(n/4)+n/2)+n=4T(n/4)+2n

≤4(2T(n/8+n/4)+2n=8T(n/8)+3n

··………

≤nT

(1)+nlogn=O(nlogn)

因此,时间复杂度为O(nlogn)。

在最坏情况下,待排序记录序列正序或逆序,每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空)。

此时,必须经过n-1次递归调用才能把所有记录定位,而且第i趟划分需要经过n-i次关键码的比较才能找到第i个记录的基准位置,因此,总的比较次数为:

∑(n-i)=n(n-1)/2=O(n*n)

记录的移动次数小于等于比较次数。

因此,时间复杂度为O(n*n)。

在平均情况下,设基准记录的关键码第k小(1≤k≤n),则有:

T(n)=(∑(T(n-k)+T(k-1))+n)/n=(2∑T(k))/n+n

这是快速排序的平均时间性能,数量级也为O(nlogn)。

快速排序是一种不稳定的排序方法。

归并排序:

一趟归并排序的操作需进行[n/2h]次归并,将r[1]~r[n]中相邻的长度为h的有序序列进行两两归并,并把结果存放到r1[1]~r1[n]中。

需要耗费O(n)时间。

整个归并排序需要进行[logn]趟,所以总时间代价是O(nlogn),这是归并排序算法最好、最坏、和平均的时间性能。

归并排序是一种稳定的排序方法。

 

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

当前位置:首页 > 人文社科 > 文化宗教

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

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