昨天又碰到了运用归并排序知识的一个题了,正好今天没有比赛,就又学习了一下归并排序的知识。并将代码总结如下,希望以后用的能更方便:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXN 10000
#define inf (1<<30)
void merge(int *num,int start,int middle,int end)
{
int n1=middle-start+1;
int n2=end-middle;
// 动态分配内存,声明两个数组容纳左右两边的数组
int *L=new int[n1+1];
int *R=new int[n2+1];
int i,j=0,k;
//将新建的两个数组赋值
for (i=0; i<n1; i++)
{
*(L+i)=*(num+start+i);
}
// 哨兵元素
*(L+n1)=inf;
for (i=0; i<n2; i++)
{
*(R+i)=*(num+middle+i+1);
}
*(R+n2)=inf;
i=0;
// 进行合并
for (k=start; k<=end; k++)
{
if(L[i]<=R[j])
{
num[k]=L[i];
i++;
}
else
{
num[k]=R[j];
j++;
}
}
delete [] L;
delete [] R;
}
void mergeSort(int *a,int low,int high) // 数组a是前闭后开的
{
if(low < high -1){
int mid = (low + high)/2;
mergeSort(a,low,mid);
mergeSort(a,mid,high);
merge(a,low,mid-1,high-1);
}
}
int a[MAXN];
int main()
{
freopen("in.txt","r",stdin);
int n;
while(cin>>n){
memset(a,0,sizeof(a));
for(int i = 0; i < n; i++)
cin>>a[i];
mergeSort(a,0,n);
for(int i = 0; i < n; i++)
printf("a[%d]=%d\t",i,a[i]);
cout<<endl;
}
return 0;
}
顺便说一下,归并排序可以用来求有序数列的逆序数,他的时间复杂度是O(nlogn),比冒泡排序O(n^2)快不少。