分治法实现归并排序

分治法基本思想

将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

归并排序

基本思想

将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成要求的排好序的集合

递归法

void MergeSort(int a[], int left, int right){
    int b[100];
    if(left<right){
        int i = (left+right)/2;
        MergeSort(a,left,i);
        MergeSort(a,i+1,right);
        Merge(a,b,left,i,right);
        Copy(a,b,left,right);
    }
}

非递归法

void MergeSort(int a[], int n){
    int *b = new int[n];
    int s = 1;
    while (s < n){
        MargePass(a, b, s, n);
        s += s;
        MargePass(b, a, s, n);
        s += s;
    }
}
void MergePass(int x[], int y[], int s, int n){
    int i = 0;
    while (i <= n-2 * s){
        Merge(x, y, i, i+s-1, i+2*s-1);
        i = i+2*s;
    }
    if (i+s<n){
        Merge(x, y, i, i+s-1, n-1);
    }else{
        for (int j = i; j < n-1; j++){
            y[j] = x[j];
        } 
    }
}

合并算法

/*合并c[n:m]和c[m+1:r]到d[n:r]*/
void Merge(int c[], int d[], int n, int m, int r){
    int i = n, j = m + 1, k = n;
    while ((i <= m) && (j <= r)){
        if (c[i] <= c[j]){
            d[k++] = c[i++];
        }else{
            d[k++] = c[j++];
        }
    }
    if (i > m){
        for (int q = j; q <= r; q++){
            d[k++] = c[q];
        }
    }else{
        for (int q = i; q <= m; q++){
            d[k++] = c[q];
        }
    }
}
void Copy(int a[], int b[], int l, int r){
    for (int i = l; i <= r; i++){
        a[i] = b[i];
    }
}

完整代码及运行结果

#include <iostream>
using namespace std;

void MergeSort(int a[],int left,int right);
void copy(int a[], int b[], int l, int r);
void Merge(int c[], int d[], int n, int m, int r);

int main(int argc, char const *argv[]){
    int count = 14;
    int array[14] = {4, 1, 2, 3, 9, 12, 10, 7, 96, 64, 100, 152, 121, 117};
    
    printf("初始时,array为:");
    for (int i = 0; i < count; i++){
        printf("%d, ", array[i]);
    }
    printf("\n");
    MergeSort(array, 0, 13);
    printf("排序后,array为:");
    for (int i = 0; i < count; i++){
        printf("%d, ", array[i]);
    }
    printf("\n");

    return 0;
}

void Copy(int a[], int b[], int l, int r){
    for (int i = l; i <= r; i++){
        a[i] = b[i];
    }
}

/*合并c[n:m]和c[m+1:r]到d[n:r]*/
void Merge(int c[], int d[], int n, int m, int r){
    int i = n, j = m + 1, k = n;
    while ((i <= m) && (j <= r)){
        if (c[i] <= c[j]){
            d[k++] = c[i++];
        }else{
            d[k++] = c[j++];
        }
    }
    if (i > m){
        for (int q = j; q <= r; q++){
            d[k++] = c[q];
        }
    }else{
        for (int q = i; q <= m; q++){
            d[k++] = c[q];
        }
    }
}

void MergeSort(int a[], int left, int right){
    int b[100];
    if(left<right){
        int i = (left+right)/2;
        MergeSort(a,left,i);
        MergeSort(a,i+1,right);
        Merge(a,b,left,i,right);
        Copy(a,b,left,right);
    }
}

运行结果

运行结果

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值