实验一算法的时间复杂度.docx
- 文档编号:27166583
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:15
- 大小:98.76KB
实验一算法的时间复杂度.docx
《实验一算法的时间复杂度.docx》由会员分享,可在线阅读,更多相关《实验一算法的时间复杂度.docx(15页珍藏版)》请在冰豆网上搜索。
实验一算法的时间复杂度
实验一算法的时间复杂度
一、实验目的与要求
熟悉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),这是归并排序算法最好、最坏、和平均的时间性能。 归并排序是一种稳定的排序方法。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验一 算法的时间复杂度 实验 算法 时间 复杂度
![提示](https://static.bdocx.com/images/bang_tan.gif)