合并排序实验报告
一、 实验内容及目的
实验内容:
对合并排序算法进行算法描述、效率分析、实验结果分析。
实验目的:
深入理解分治法的思想,学习合并排序的排序方法,对合并排序进行算法分析,通过与其他排序算法比较,体会分治思想的优点。
分析的指标:
在相同数据规模的情况下的插入排序算法和合并算法代码运行时间。
二、实验方案
图1实验硬件平台 |
实验环境:Windows10 + Dev-C++
+ 硬盘大小100GB + 8核处理器 + 16GB内存
合并排序伪代码:
运行时间采集方式:
图 2计时方法 |
使用系统自带函数clock(),这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元数。在程序开始时先记录一个时钟数,在程序结束时再记录一个时钟数。将两个时钟数相减并除以一秒钟内CPU运行的时钟周期数(宏定义为CLOCKS_PER_SEC)就能得到程序运行时间。
三、结果及分析
测试数据规模:8个随机无序数组。范围1x10^3~1x10^ 6
表 1 对比图 |
算法流程:
1) 将数组A[1,n]排序问题分解为A[1,n/2]和A[n/2+1,n]的排序问题
2) 递归解决子问题得到两个有序的子数组
3) 将两个有序的子数组合并为一个有序的数组
算法详细流程:
下面是Mergesort函数:
递归的终止条件 仅有一个元素 |
1.将原数组一分为二,体现“分”的部分
2.对每个分开的数组再次进行递归,求解子问题
3.合并每个子问题的解
下面是Merge函数:
1.遍历子数组,按从小到大的顺序进行合并
2.添加剩余元素保证有序
算法复杂度分析:
T(n):完成Mergesort(A,1,n)的运行时间,为了便于分析,假设n是2的幂。
先观察Merge函数:
可以看出Merge函数是将两个数组合并,其时间复杂度为O(n)
再观察Mergesort函数
得出Mergesort的运行时间:
进而我们可以算出合并排序的算法时间复杂度:
四、总结
分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后在合并这些子问题的解来解决原问题的解。
合并排序再最坏情况下的比较次数十分接近基于比较的排序算法在理论上能够达到的最少次数。其明显的一个优点在于其稳定性。主要缺点是该算法需要额外的空间。在带排序数组非常大的时候,可能空间开销会非常大,这是可以改进的地方之一。
遇到的问题:
1) 最开始在Mergesort中将两个数组分开时会创建大小相同的B和C数组,其数组长度都和原排序数组相同,在数组特别大时会爆内存。通过改进,分配大小合适的数组空间,可以解决这个问题。 使用malloc动态分配合适的数组空间。
2) 在测试数据特别大的时候,通过控制台输入不了。最后使用读取文件的操作,可以解决这个问题。
五、参考文献及附录
clayyjh. C语言 记录程序的执行时间[EB/OL] [2021-03-12].https://www.cnblogs.com/clayyjh/p/14526665.html
小乔流水人家. C语言 查看运行程序所需要的时间和占用的内存[EB/OL] [2017-02-22].https://www.cnblogs.com/BeautyFuture/articles/6428551.html
挺的博客 归并排序(C语言版)[EB/OL] [ 2019-05-02 ]. https://blog.csdn.net/baidu_15547923/article/details/89742717?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163850559416780264068627%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163850559416780264068627&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-10-89742717.first_rank_v2_pc_rank_v29&utm_term=%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F%E4%BC%AA%E4%BB%A3%E7%A0%81&spm=1018.2226.3001.4187
Koala朱 归并排序算法的伪代码和实现 [EB/OL] [ 2018-04-18 ].
附录:
合并排序算法:
#include<bits/stdc++.h> using namespace std; void merge(int A[], int L[], int R[], int l, int r); void mergesort(int A[],int n) { if(n>1) { //多于一个元素才需要排序 int mid=n/2; int *B=(int*)malloc(sizeof(int)*mid); int *C=(int*)malloc(sizeof(int)*(n-mid)); for(int i=0; i<mid; i++) B[i]=A[i]; //左半部分 for(int j=mid; j<n; j++) C[j-mid]=A[j]; //右半部分序列 mergesort(B,mid); mergesort(C,n-mid); merge(A,B,C,mid,n-mid); free(B); free(C); } } void merge(int A[],int B[],int C[],int p,int q) { int i=0,j=0,k=0; while(i<p&&j<q) { if(B[i]<=C[j]) A[k]=B[i++]; else A[k]=C[j++]; k++; } while(i<p) { A[k++]=B[i++]; } while(j<q) { A[k++]=C[j++]; } } int main(){ int A[1010]; int n; cin >> n; for(int i = 0 ; i < n ; i++){ cin >> A[i]; } mergesort(A,n); for(int i=0;i<n;i++){ if((i+1)%10==0){ printf("%d\n",A[i]); }else{ if(i==n-1){ printf("%d\n",A[i]); }else{ printf("%d ",A[i]); } } } }
标签:排序,int,2522%,合并,算法,数组,实验报告,SWUST From: https://www.cnblogs.com/Sensei/p/17751444.html