当前位置:   article > 正文

归并排序(递归实现)_用递归算法实现归并排序,在主函数中输入一些数据,并通过该递归函数进行排序,并将

用递归算法实现归并排序,在主函数中输入一些数据,并通过该递归函数进行排序,并将

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法。
归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

下段代码中,将a[] 和 b[]合并到一个数组T[]

int a[5] = {1,3,5,7,9};
int b[5] = {,2,4,6,8,10};
int T[10] = {0};
for(int i =0;i<5;i++)
    T[i] = a[i];
for(int i =5;i<10;i++)
    T[i] = b[i];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

再进行归并

#include "stdio.h"

void Merge(int A[],int TempA[],int L,int R,int RightEnd)
{
    int LeftEnd = R-1;    //左边终点位置
    int temp = L;       //存放结果排序后的数组的初始位置
    int NumElements = RightEnd-L+1;  //记录总数
    while(L<=LeftEnd && R<= RightEnd)
    {
        if(A[L]<=A[R]) TempA[temp++] = A[L++];/* 将左边元素复制到TmpA */
        else    TempA[temp++] = A[R++];/* 将右边元素复制到TmpA */
    }
    while(L<=LeftEnd)
        TempA[temp++] = A[L++];/* 直接复制左边剩下的 */
    while(R<=RightEnd)
        TempA[temp++] = A[R++];  /* 直接复制右边剩下的 */
    for( i = 0; i < NumElements; i++, RightEnd -- )
         A[RightEnd] = TmpA[RightEnd]; /* 将有序的TmpA[]复制回A[] */

}

int main()
{
    int a[10]={1,3,5,7,9,2,4,6,8,10};
    int b[10]={0};
    Merge(a,b,0,5,9);
    for(int i =0;i<10;i++)
        printf("%d",a[i]);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

当然,你会有疑问,为什么给我们的两个数组,一开始就是已经排好序的?其实上面只是演示的过程。在现实的问题中,往往会给我们一个杂乱无序的数组。结合上面的例子,我们可以尝试这么做:分而治之。如下图所示:

这里写图片描述

分而治之的关键在于:
将一个无序的数组分成等分的两小段。接着呢,又可以将两小段每一段再分。。。不断重复直到每一段都无法再分的时候,也就是每一段,都只有一个元素的时候,无法再分,即下面代码中 L<RightEnd 的时候,将数组中的数通过归并排序的核心算法进行排序,并保存到TempA[]中。
注意这是递归。

void MSort(int A[],int TempA[],int L,int RightEnd)
{/* 核心递归排序函数 */ 
    int Center;
    if(L<RightEnd){
        Center = (L+RightEnd)/2;
        MSort(A,TempA,L,Center); /* 递归解决左边 */ 
        MSort(A,TempA,Center+1,RightEnd);/* 递归解决右边 */  
        Merge(A,TempA,L,Center+1,RightEnd);/* 合并两段有序序列 */ 
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里写图片描述

之后,在将TempA[] 中的数据依次保存回A[]

这里写图片描述

我们把上面的代码优化一下,即可以提供统一函数的接口。

void Merge_Sort(int A[],int n)
{/* 归并排序 */
    int *TempA = (int*)malloc(sizeof(int)*n);
    if(TempA !=NULL){
        MSort(A,TempA,0,n-1);
        free(A);
    }
    else Error("空间不足");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

统一代码:

#include "stdio.h"
#include "stdlib.h"
/* L = 左边起始位置, R = 右边起始位置, RightEnd = 右边终点位置*/
void Merge(int A[],int TempA[],int L,int R,int RightEnd)
{/* 将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列 */
    int LeftEnd = R-1;    //左边终点位置
    int temp = L;       //存放结果排序后的数组的初始位置
    int NumElements = RightEnd-L+1;  //记录总数
    while(L<=LeftEnd && R<= RightEnd)
    {
        if(A[L]<=A[R]) TempA[temp++] = A[L++];/* 将左边元素复制到TmpA */
        else    TempA[temp++] = A[R++];/* 将右边元素复制到TmpA */
    }
    while(L<=LeftEnd)
        TempA[temp++] = A[L++]; /* 直接复制左边剩下的 */
    while(R<=RightEnd)
        TempA[temp++] = A[R++]; /* 直接复制右边剩下的 */

   for( i = 0; i < NumElements; i++, RightEnd -- )
         A[RightEnd] = TmpA[RightEnd]; /* 将有序的TmpA[]复制回A[] */
}


void MSort(int A[],int TempA[],int L,int RightEnd)
{/* 核心递归排序函数 */ 
    int Center;
    if(L<RightEnd){
        Center = (L+RightEnd)/2;
        MSort(A,TempA,L,Center); /* 递归解决左边 */ 
        MSort(A,TempA,Center+1,RightEnd);/* 递归解决右边 */  
        Merge(A,TempA,L,Center+1,RightEnd);/* 合并两段有序序列 */ 
    }
}

void Merge_Sort(int A[],int n)
{/* 归并排序 */
    int *TempA = (int*)malloc(sizeof(int)*n);
    if(TempA !=NULL){
        MSort(A,TempA,0,n-1);
        free(A);
    }
    else printf("空间不足\n");
}


int main()
{
    int a[10]={1,3,5,7,9,2,4,6,8,10};
    //int b[10]={0};
    //Merge(a,b,0,5,9);
    Merge_Sort(a,10);
    for(int i =0;i<10;i++)
        printf("%d",a[i]);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/454826
推荐阅读
相关标签
  

闽ICP备14008679号