数据结构与算法 ---- 二路归并排序

二路归并排序主要运用了“分治算法”,分治算法就是将一个大的问题划分为n个规模较小而结构相似的子问题。

这些子问题解决的方法都是类似的,解决掉这些小的问题之后,归并子问题的结果,就得到了“大”问题的解。

二路归并排序主旨是“分解”与“归并”

分解:

1.将一个数组分成两个数组,分别对两个数组进行排序。

2.循环第一步,直到划分出来的“小数组”只包含一个元素,只有一个元素的数组默认为已经排好序。

归并:

1.将两个有序的数组合并到一个大的数组中。

2.从最小的只包含一个元素的数组开始两两合并。此时,合并好的数组也是有序的。
    在这里插入图片描述
举例说明:

1.图中原始数组为{2,4,7,5,8,1,3,6},数组中元素的个数为8个。首先将8个元素的数组二分,每次分解后,

数组中元素的数目为原数组的一般。直到分解为只含有一个元素的数组。

2.将小的数组按序合并,每次合并后数组的大小为上层数组的一倍。此时数组中的元素都是按序排列的。

3.在合并两个有序数组。如图2

(1) 合并时,有两个指针分别指向有序数组A和B的起始元素,比较指针所指元素的大小,如果A[i]较小,则将A[i]

存入数组C中,并且将i后移。循环比较i和j所指的元素。

(2)当一个数组A的元素全部排之后,数组B中的指针就并没有指向B的末尾位置,将B中剩余元素全部存入到C中。

#include <stdio.h>
#include <stdlib.h>

void Merge(int array[], int p, int q, int r);
void MergeSort(int array[], int p, int q);

int main()
{
    int array[8] = {5,2,4,7,1,3,2,6};
    int i = 0;

    MergeSort(array, 0, 7);

    for(i; i < 8; i++)
        printf("%d  ", array[i]);
    return 0;
}

//合并过程
void Merge(int array[], int p, int r, int q)
{
    int n1 = r - p + 1;
    int n2 = q - r;

    int *L;
    L = (int*)malloc(sizeof(int)*n1);
    int *R;
    R = (int*)malloc(sizeof(int)*n2);

    int i = 0;
    int j = 0;

    for(i; i < n1; i++)
        L[i] = array[i + p];
    for(j; j < n2; j++)
        R[j] = array[j + r  +1];

    i = j = 0;

    int k = p;

    while(i!=n1 && j!= n2)
    {
        if(L[i] <= R[j])
            array[k++] = L[i++];
        else
            array[k++] = R[j++];
    }

    while(i < n1)
        array[k++] = L[i++];
    while(j < n2)
        array[k++] = R[j++];

    free(L);
    free(R);
}

//分解过程 
void MergeSort(int array[], int p, int q)
{
    if(p < q)
    {
        int r = (p+q)/2;
        MergeSort(array, p, r);
        MergeSort(array, r+1, q);
        Merge(array,p, r, q);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值