【ZCMU2149】wjw的排序问题(归并排序)

点击打开链接

2149: wjw的排序问题

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 78  Solved: 28
[Submit][Status][Web Board]

Description

菜鸡wjw觉得最近对排序算法的理解又上了一个档次,于是准备研究一下自己会的所有排序算法,经过测试,他写的所有代码里最快的只有一句话"std::sort(a,a+len)",于是他终于发现自己依旧是个菜鸡...

那么问题来了,如果不用"std::sort()",你能写出什么样的排序代码呢?

Input

一组数据,第一行一个n表示序列长度(1<=n<=3000000)

第二行包含n个数字,用空格隔开

Output

升序排序后的结果,用空格隔开,末尾没有空格

Sample Input

51 3 2 4 5

Sample Output

1 2 3 4 5

HINT

Source

jnxxhzz

解题思路:

这题本来以为是考快排的,但是用了最基础的快排发现WA了,我猜可能是快排不稳定的关系,最后也没有实现优化,所以这里用了是时间复杂度和快排一样的更稳定的归并排序,第一次接触归并,归并应该是一个先分治再归并的过程,相当于把一个大问题分解很多的小问题,求解每个小问题,再将一个个小问题合起来解决大问题。

代码:

#include <stdlib.h>
#include <stdio.h>
 
void Merge(int sourceArr[],int tempArr[], int startIndex, int midIndex, int endIndex)
{
    int i = startIndex, j=midIndex+1, k = startIndex;
    while(i!=midIndex+1 && j!=endIndex+1)
    {
        if(sourceArr[i] > sourceArr[j])
            tempArr[k++] = sourceArr[j++];  
        else
            tempArr[k++] = sourceArr[i++];
    }
    while(i != midIndex+1)
        tempArr[k++] = sourceArr[i++];
    while(j != endIndex+1)
        tempArr[k++] = sourceArr[j++];
    for(i=startIndex; i<=endIndex; i++)
        sourceArr[i] = tempArr[i];
}
 
//内部使用递归
void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex)
{
    int midIndex;
    if(startIndex < endIndex)
    {
        midIndex = (startIndex + endIndex) / 2;   
        MergeSort(sourceArr, tempArr, startIndex, midIndex);  //使用递归的方式将大的数组划分成小的 
        MergeSort(sourceArr, tempArr, midIndex+1, endIndex);
        Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);
    }
}
 
int main()
{
	int n;
	scanf("%d",&n);
    int a[n];
    int i, b[n];
    for(i=0;i<n;i++)scanf("%d",&a[i]);
    MergeSort(a, b, 0, n-1);
    for(i=0; i<n-1; i++)
        printf("%d ", a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/80624918