插入排序算法与归并排序算法比较
- 实验目的
通过插入排序算法与归并排序算法效率对比体会算法在求解问题中的重要性。
- 实验内容
- 分别编写函数实现插入排序算法和归并排序算法;
- 利用随机函数产生大量数据存入数组作为待排序列;
- 分别测试待排序列数据量为1000、1万、10万、100万、1000万的情况下两种算法各自的运行时间,通过对比分析研究哪个算法在数据量逐渐增大时效率高;
- 对两种算法进行理论分析哪个算法效率高;
- 与实验数据对照,检查是否实验结果验证了理论分析的结果。
- 算法伪代码
直接插入排序:
for j=2 to A.length
key=A[j]
i=j-1;
while i>0 and A[i]>key
A[i+1]=A[i]
i=i-1
A[i+1]=key
归并排序:
MERGE(A,p,q,r)
n1=q-p+1;
n2=r-q;
for i=0 to n1
L[i]=A[p+i-1]
for j=0 to n2
R[j]=A[q+j]
L[n1]=INF//假设1000是无穷大
R[n2]=INF
i=j=1
for k=p to r
if(L[i]<=R[j])
A[k]=L[i]
i=i+1
else
A[k]=R[j]
j=j+1
MERGE_SORT(A,p,r)
if p<r
q=floor((p+r)/2)
MERGE_SORT(A,p,q)
MERGE_SORT(A,q+1,r)
MERGE(A,p,q,r)
- 理论分析
- 每个算法时间复杂度分析
直接插入排序的时间复杂度为Q(n2),归并排序的时间复杂度为Q(nlgn)。
- 结论
归并排序的算法比直接插入排序的算法的增长速度慢,也就是说,当数据量大的时候,归并排序将占有优势,速度快于插入排序。当数据量小的时候,插入排序将占有优势,速度快于归并排序。。
测试数据:1000、1万、10万、100万、1000万
运行结果界面截图
- 性能测试
测试结果示例:(单位:微秒)
算法名称
运行时间/s 数据量 | 1000 | 1万 | 10万 | 100万 | 1000万 | 平均运行时间 |
插入排序 | 838.1 | 80828.8 | 7.40966e+006 | 9.17404e+008 | ∞ | Q(n2) |
归并排序 | 152.8 | 1793.5 | 17411 | 213525 | 2.31033e+006 | Q(nlgn) |
七、源代码
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<set>
#include<windows.h>
const int INF = 1e8;
const long long maxn = 1e8 + 10;
const long long mod = 1e9 + 7;
int a1[maxn], a2[maxn];
int L[maxn]= {0};
int R[maxn]= {0};
using namespace std;
void insertSort(int *a,int n)//直接插入排序
{
int tmp,j;
for(int i=1; i<n; i++)
{
tmp=a[i];
j=i-1;
while(j>=0&&tmp<a[j])
{
a[j+1]=a[j];
j--;
}
a[j+1]=tmp;
}
}
void Marge(int *a,int left,int mid,int right)
{
int n1=mid-left+1;
int n2=right-mid;
int i,j;
for(i=0; i<=n1; i++)
L[i]=a[left+i-1];
for(j=0; j<=n2; j++)
R[j]=a[mid+j];
L[n1+1]=INF;
R[n2+1]=INF;
i=1;
j=1;
for(int k=left; k<=right; k++)
{
if(L[i]<=R[j])
{
a[k]=L[i];
i++;
}
else
{
a[k]=R[j];
j++;
}
}
}
void MargeSort(int *a,int left,int right)
{
if(left<right)
{
int mid=(left+right)/2;
MargeSort(a,left,mid);
MargeSort(a,mid+1,right);
Marge(a,left,mid,right);
}
else
return ;
}
int main()
{
ios::sync_with_stdio(false);//C++为了兼容C而采取的保守措施
cin.tie(0), cout.tie(0);//减少cin,cout时间
int n;
while(~scanf("%d",&n))
{
for(int i = 0; i < n; i++)
{
a1[i] = rand() % 100000000;
a2[i] = a1[i];
}
/*cout << "待排序的数字:" <<endl;
for(int i=0; i<10; i++)
{
cout << a1[i] << endl;
}*/
//首先获取CPU频率
double run_time;
_LARGE_INTEGER time_start;//开始时间
_LARGE_INTEGER time_over;//结束时间
double dqFreq;//计时器频率
LARGE_INTEGER f;//计时器频率
QueryPerformanceFrequency(&f);
dqFreq=(double)f.QuadPart;
cout<<"CPU主频:"<<dqFreq<<"kHz"<<endl; //单位为秒,精度为000/(cpu主频)微秒
QueryPerformanceCounter(&time_start);
insertSort(a1, n); //插入排序计时
QueryPerformanceCounter(&time_over);
run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;//乘以1000000把单位由秒化为微秒,精度为1000 000/(cpu主频)微秒
cout<<"插入排序计时:"<<run_time<<endl;
/*cout << "插入排序后的数字:" <<endl;
for(int i = 0; i < n; i++)
{
cout << a1[i] << ' ';
cout << endl*/
QueryPerformanceCounter(&time_start);
MargeSort(a2,0,n-1);//归并排序计时
QueryPerformanceCounter(&time_over);
run_time=1000000*(time_over.QuadPart-time_start.QuadPart)/dqFreq;//乘以1000000把单位由秒化为微秒,精度为1000 000/(cpu主频)微秒
cout<<"归并排序计时:"<<run_time<<endl;
/*cout << "归并排序后的数字:" <<endl;
for(int i = 0; i < n; i++)
{
cout << a2[i] << ' ';
}
cout << endl;*/
}
return 0;
}