归并排序是面试常考的排序算法,也有一些题目是归并排序的变形,比如数组的逆序对问题,后面我会更新这个算法。归并是典型的分治算法,比较简单,直接上代码。
void merge(int *a,int first,int mid,int last,int *temp)
{
int i=first,j=mid+1;
int k=0;
while(i<=mid && j<=last)
{
if(a[i]<=a[j])
{
temp[k++]=a[i++];
}
else
{
temp[k++]=a[j++];
}
}
while(i<=mid)
temp[k++]=a[i++];
while(j<=last)
temp[k++]=a[j++];
for(i=0;i<k;i++)
a[first+i]=temp[i];
}
void mergeSort(int *a,int first,int last,int *temp)
{
if(first<last)
{
int mid=(first+last)>>1;
mergeSort(a,first,mid,temp);
mergeSort(a,mid+1,last,temp);
merge(a,first,mid,last,temp);
}
}
复杂度分析:整个归并需要logn趟,俩个有序序列合并成有序时间复杂度o(m+n),因此总的时间复杂度是o(nlgn).其实可以把归并排序看成是二叉树的后续遍历。
来自百度的一张图(18应为10)。