归并排序是一种时间复杂度很优的算法,他到底有多优下面分析了再写,但就目前所知至少比冒泡排序要优
先来讲一下归并排序的大体思路:首先将要排序的数组,进行拆分,但拆分为单个时,即单个子序列有序(该过程通过递“归”);然后再合并单个元素,得到单个有序子序列,最终得到有序序列(该过程为“并”)
画图来仔细分析:
归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)
通过这幅图的分析,我们可以得到归并排序的时间复杂度为O(N*logN),而冒泡排序的时间复杂度为O(N*N)。
整体思路是有了,可是它的递归过程还是有必要分析一下的:
为了说明问题我只花了它的流程的一半,其它的也是一样的。
下面我们将整个思考过程通过代码来实现一下:
1.先写合并两的子序列的函数
void MergeArray(int* a,int bigen,int mid,int end,int* temp)
{
int b1 = bigen,e1 = mid;
int b2 = mid + 1,e2 = end;
int k = 0;
while(b1<=e1&&b2<=e2)
{
if(a[b1]<a[b2])
temp[k++] = a[b1++];
else
temp[k++] = a[b2++];
}
while(b1<=e1)
temp[k++] = a[b1++];
while(b2<=e2)
temp[k++] = a[b2++];
for(int i = 0;i<k;i++)
a[bigen+i] = temp[i];
}
2.核心部分,归并递归控制
void MergeSort(int* a,int bigen,int end,int* temp)
{
if(bigen<end)//当只有一个元素时回退,拆分完成
{
int mid = (bigen+end)>>1;//找到中间进行拆分
MergeSort(a,bigen,mid,temp)
MergeSort(a,mid+1,end,temp);//右子序列再拆分,进行合并达到//右边有序
MergeArray(a,bigen,mid,end,temp);//对子序列进行合并
}
}
3.归并排序代码:
void mergesort(int* a, int n)
{
int* p = new int[n];
MergeSort(a,0,n-1,p);
delete [] p;
}
4.用来测试的主函数:
int main()
{
int a[10] = {10,9,8,7,6,5,4,3,2,1};
const int n = 10;
mergesort(a,n);
for(int i = 0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
我相信通过上面的画图分析和代码的详细注释结合,这个算应该可以理解吧!!