归并排序——归并、两路归并递归及非递归

排序9.5 归并排序9.5.1 归并9.5.2 两路归并排序9.5.3 递归的归并排序总结9.5 归并排序9.5.1 归并所谓归并,就是将两个或两个以上的有序表合并成一个新的有序表。有两个已经排好序的有序表A[1]~ A[n]和 B[1]~ B[m]通过归并把它们合成一个有序表C[1]~C[m+n]。这种归并方法称为两路归并。其基本思想是:设有两个有序表A和B,其数据元素个数(表长)分别为n和m,变最i和j 分别是表A和表B的当前检测指针;设表C是归并后的新有序表,变量k是它的当前存放指针。开始
摘要由CSDN通过智能技术生成

9.5 归并排序

9.5.1 归并

  1. 所谓归并,就是将两个或两个以上的有序表合并成一个新的有序表。有两个已经排好序的有序表A[1]~ A[n]和 B[1]~ B[m]通过归并把它们合成一个有序表C[1]~C[m+n]。这种归并方法称为两路归并。
  2. 其基本思想是:设有两个有序表A和B,其数据元素个数(表长)分别为n和m,变最i和j 分别是表A和表B的当前检测指针;设表C是归并后的新有序表,变量k是它的当前存放指针。
    开始时i、j、k都分别指向A、B、C三个表的起始位置;然后根据A[i]与B[i]的关键字的大小,把关键字小的数据元素放到新表C[k];且相应的检测指针(i或j)和存放指针k增加1。如此循环,当i与j中有一个已经超出表长时,将另一个表中的剩余部分照抄到新表C[k]~C[m+n]中·。
    在这里插入图片描述
  3. 两路归并算法:
    两个待归并的有序表省首尾相接存放在数组elem[]中,其中第一个表的下标范围是从low到 mid,另一个表的下标范围从 mid+1 到 high。
    前一个表中有 mid-low+1个数据元素后一个表中有high-mid 个数据元素。归并时新有序表先存放在一个辅助数组tmpElem[]中,完成归并后再把tmpElem[]中元素放回数组elem[]中。
  4. 代码实现
template<class ElemType> void Merge(ElemType elem[],int low,int mid,int high)
{
   
    ElemType *tmpElem=new ElemType[high+1];//定义临时数组
    int i=low,j=mid+1,k=low;
    //i为归并时前一表当前元素的下标,j为归并后一表当前元素的下标,
    //k为tmpElem中当前元素的下标
    while(i<=mid && j<=high)
        if(elem[i]<=elem[j])
            tmpElem[k++]=elem[i++];
        else
            tmpElem[k++]=elem[j++];
    while(i<=mid)//归并elem[low..mid]中剩余元素
        tmpElem[k++]=elem[i++];
    while(j<=high)//归并elem[mid+1..high]中剩余元素
        tmpElem[k++]=elem[j++];
    for(i=low;i<=high;i++)//将tmpElem复制回elem
        elem[i]=tmpElem[i];
    delete [] tmpElem;
}

在上述算法中,所有数据元素都将被移入辅助数组 tmpElem[]中。所以,总的数据元素移动次数为(mid-low+1)+(high-mid)=high-low+1;在 while循环中,每进行一次关键字的比较,就有一个数据元素被移入辅助数组 tmpElem[],而在 while循环后面数据元素不进行比较直接被移入辅助数组 tmpElem[]中。所以,在算法实现时关键字比较次数不会超过数据元素的移动次数

9.5.2 两路归并排序

  1. 两路归并排序(merge sort)就是利用两路归并算法进行排序。
  2. 其算法基本思想是:
    假设初始数据表有n个数据元素,首先把它看成是长度为1的首尾相接的n个有序子表(以后称它们为归并项),先做两两归并,得⌈n/2⌉个长度为2的归并项(如果n为奇数,则最后一个归并项的长度为1);再做两两归并……如此重复,最后得到一个长度为n的有序序列。两路归并排序由多趟归并过程实现。第一趟令归并项的长度为len=1,以后每执行一趟后将len加倍。
  3. 下面先讨论一趟归并的情形:设数组elem[0]到elem[n-1]中的n个数据元素已经分为一些长度为len的归并项,将这些归并项两两归并,归并成一些长度为2len 的归并项。如果n不是2len的整数倍,则一趟归并到最后,可能遇到以下两种情形。
    1)剩下一个长度为len 的归并项和另一个长度不足len的归并项,可用一次 merge算法,将它们归并成一个长度小于2*len的归并项。
    2)只剩下一个归并项,其长度小于或等于 len,此时就不需要进行归并了。
template
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值