理论基础 —— 排序 —— 归并排序

【概述】

归并排序是一种稳定的排序方法,其是分治策略的一个非常典型的应用。

其基本思想是:将 n 个待排序的记录看成是 n 个长度为 1 的有序序列,然后两两进行归并,第一轮得到 [n/2] 个长度为 2 的有序序列,第二轮得到 [n/4] 个长度为 4 的有序序列,以此类推,直到得到一个长度为 n 的有序序列。

【排序过程】

归并排序的核心是归并操作,即将两个已经排序的序列合并成一个序列的操作,其步骤如下:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
  4. 重复步骤 3 直到某一指针到达序列尾
  5. 将另一序列剩下的所有元素直接复制到合并序列尾

在实际排序过程中,通过对归并操作的递归调用,即可完成归并排序。

          

                              排序过程                                                宏观过程

【时空复杂度分析】

一趟归并排序需要将待排序序列扫描一遍,其时间复杂度为 O(n),而整个归并排序需要进行 \left \lceil log_2n \right \rceil 趟,因此,总的时间复杂度为 O(nlogn)

由于待排序序列并不影响归并排序的过程,因此无论是最好、最坏时间复杂度,还是平均时间复杂度,均为 O(nlogn)

此外,归并排序再归并过程中,需要与待排序记录序列同样数量的存储空间,以便存放归并结果,因此其空间复杂度为 O(n)

【源程序】

void mergeArray(int a[],int left,int mid,int right,int temp[]){
    int i=left,j=mid+1;
    int k=0;

    while(i<=mid&&j<=right){
        if(a[i]<=a[j])//取a[i]与a[j]中的小者放入temp[k]
            temp[k++]=a[i++];
        else
            temp[k++]=a[j++];
    }
    while(i<=mid)//第一个子序列未处理完
        temp[k++]=a[i++];
    while(j<=right)//第二个子序列未处理完
        temp[k++]=a[j++];

    for(int i=0;i<k;i++)//将数组temp中的值返回数组a
        a[left+i]=temp[i];
}
void mergeSort(int a[],int left,int right,int temp[]){
    if(left<right){
        int mid=(left+right)/2;
        mergeSort(a,left,mid,temp);//左边有序
        mergeSort(a,mid+1,right,temp);//右边有序
        mergeArray(a,left,mid,right,temp);//将二个有序数列合并
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值