排序————归并排序

归并排序是一种时间复杂度很优的算法,他到底有多优下面分析了再写,但就目前所知至少比冒泡排序要优
先来讲一下归并排序的大体思路:首先将要排序的数组,进行拆分,但拆分为单个时,即单个子序列有序(该过程通过递“归”);然后再合并单个元素,得到单个有序子序列,最终得到有序序列(该过程为“并”
画图来仔细分析:

这里写图片描述

归并排序的效率是比较高的,设数列长为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)//合并
//数组[bigen...mid]和数组[mid+1 ... end]
{
    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++];
    //将a数组分出去的元素,并合并好的顺序元素段,还会a对应的位置
    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;
}
我相信通过上面的画图分析和代码的详细注释结合,这个算应该可以理解吧!!

猜你喜欢

转载自blog.csdn.net/FangXiaXin/article/details/80581237