HDU 3743 归并排序模板题

归并排序续讲

先贴代码

long long count = 0;
int a[1000000 + 5];
int b[1000000 + 5];
void Merge(int sourceArr[], int tempArr[], int starIndex, int midIndex, int endIndex)
{
    int i = starIndex;
    int j = midIndex + 1;
    int k = starIndex;

    while (i != midIndex + 1 && j != endIndex + 1)
    {
        if (sourceArr[i] < sourceArr[j])
            tempArr[k++] = sourceArr[i++];
        else
        {
            tempArr[k++] = sourceArr[j++];
            count += midIndex - i + 1;// *&*&*&*&*&*&*&*&*&
        }
    }
    while (i != midIndex + 1)
        tempArr[k++] = sourceArr[i++];

    while (j != endIndex + 1)
        tempArr[k++] = sourceArr[j++];
}

void Merge_sort(int sourceArr[], int tempArr[], int starIndex, int endIndex)
{
    int midIndex;
    if (starIndex < endIndex)
    {
        midIndex = (starIndex + endIndex) / 2;
        Merge_sort(sourceArr, tempArr, starIndex, midIndex);
        Merge_sort(sourceArr, tempArr, midIndex + 1, endIndex);
        Merge(sourceArr, tempArr, starIndex, midIndex, endIndex);

    }
}

上面的是标准的归并函数;

我们注意到在注释标记的地方加上了count来统计一个数值,这个数值代表的就是在排序中交换的总步骤。

下面是解释:

start\ 归并排序的过程实际是2个已经排好序的数列(A, B)进行合并(放入C数组)的过程,

在合并的过程中如果从A中选取数据,那么不计入步数统计,因为A数列默认在前,从前面选取数据不用交换

同理如果从B中拿数据就一定是从后面交换到前面的,也就是说一定经过了交换

如果是下面的直接放入C数组的元素是不用计入步数,因为在之前生成的时候就已经计入了步骤\end

对于解决交换次数 交换路径 等问题上文是一个时间复杂度为N log N的模板;

最后总代码

#include<stdio.h>
long long count = 0;
int a[1000000 + 5];
int b[1000000 + 5];
void Merge(int sourceArr[], int tempArr[], int starIndex, int midIndex, int endIndex)
{
    int i = starIndex;
    int j = midIndex + 1;
    int k = starIndex;

    while (i != midIndex + 1 && j != endIndex + 1)
    {
        if (sourceArr[i] < sourceArr[j])
            tempArr[k++] = sourceArr[i++];
        else
        {
            tempArr[k++] = sourceArr[j++];
            count += midIndex - i + 1;
        }
    }
    while (i != midIndex + 1)
        tempArr[k++] = sourceArr[i++];

    while (j != endIndex + 1)
        tempArr[k++] = sourceArr[j++];
}

void Merge_sort(int sourceArr[], int tempArr[], int starIndex, int endIndex)
{
    int midIndex;
    if (starIndex < endIndex)
    {
        midIndex = (starIndex + endIndex) / 2;
        Merge_sort(sourceArr, tempArr, starIndex, midIndex);
        Merge_sort(sourceArr, tempArr, midIndex + 1, endIndex);
        Merge(sourceArr, tempArr, starIndex, midIndex, endIndex);

    }
}


int main(void)
{
    int t, i, k, min, temp;

    while (scanf_s("%d", &t) != EOF)
    {
        count = 0;
        getchar();
        for (i = 0; i < t; i++)
        {
            scanf_s("%d", &a[i]);
        }
        Merge_sort(a, b, 0,  t - 1);
        min = count;
        for (k = 0; k < t - 1; k++)
        {
            count = 0;
            a[k + t] = a[k];
            Merge_sort(a, b, k + 1, k + t);
            if (count < min)
                min = count;
        }

        printf("%d\n", min + 1);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值