合并排序中子排序结果放回原数组时应注意的问题

Posted 木小猪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并排序中子排序结果放回原数组时应注意的问题相关的知识,希望对你有一定的参考价值。

  在对数组进行合并排序时,往往会用到递归。而一遇上递归,就很容易被迷住。毕竟,递归的过程细节是很烧脑的。这时,如果再来几个子函数,就更嗨了。下面就说一说我自己遇见的这个递归:

  template<class T>

  void MergeSort(T a[],int left,int right){
    int t=right-left;
    t++;
    T b[t];//每次递归,定义一个与处理数据数量相等大小的数组,暂存处理后的数组
    if(left<right){
    int i=(left+right)/2;
    MergeSort(a,left,i);//这两次不同形式的递归结果为
    MergeSort(a,i+1,right);//将数组一分为二后两侧顺序排好
    Merge(a,b,left,i,right);//将排完顺序的半成品数组完全排好:即合并到数组b
    Copy(a,b,left,right);//将排好序的数组重新放回数组a
    }
  }

  下面我们就具体说一说Merege和Copy这两个子函数的具体细节:

  template<class T>

  void Merge(T a[],T b[],int left,int mid,int right){//将当前范围(left-right)中的数据按一定次序存入b数组
      int i=left,j=mid+1;
      int t=0;
      while(i<=mid&&j<=right){
      if(a[i]>a[j]){
        b[t++]=a[j++];
      }else{
       b[t++]=a[i++];
      }
    }
    while(i<=mid){
    b[t++]=a[i++];
    }
    while(j<=right){
    b[t++]=a[j++];
    }

  }

  template<class T>

  void Copy(T a[],T b[],int left,int right){//将最后排好顺序的元素重新放回a

    int t=0;//此处应注意的是我们处理的数据是a数组中的,而合并排序时将每次排好顺序的数据放回a中,此时要特别注意放回的方式,要将数据放回原来的索引范围,

    for(int i=left;i<=right;i++){//而不是单纯的放回去,下面给出一张图帮助理解
    a[i]=b[t++];
    }
  }

  template<class T>

  void Copy(T a[],T b[],int left,int right){//这是将复制简单理解为复制回a后的错误函数
    int t=right-left+1;
    for(int i=0;i<t;i++){
    a[i]=b[i];//这样的后果就是改变a数组原有内容,造成意想不到的计算结果
    }
  }

以上是关于合并排序中子排序结果放回原数组时应注意的问题的主要内容,如果未能解决你的问题,请参考以下文章

归并排序

解决UNION ALL合并两个结果集后排序的问题

分治法合并排序

归并排序

合并排序

归并排序