AcWing 787.归并排序(C++算法)

AcWing 787.归并排序

1、题目(来源于AcWing):
给定你一个长度为n的整数数列。

请你使用归并排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式
输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在1~109范围内),表示整个数列。

输出格式
输出共一行,包含 n 个整数,表示排好序的数列。

数据范围
1≤n≤100000

输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5

2、基本思想:
用分治的思想。将一组数据从中间平分为两组,用递归将左右两组数据分别按从大到小的顺序排好序(用后面那个合二为一的方法),然后合二为一,即用两个指针分别指向两组数据的最小值,比较两个指针所指的数,小的就依次存入一个新的数组,若有左(右)组数据已排完,则将右(左)组剩下未排完的数直接一次存入新数组当中。

3、步骤:
①确定分界点:mid = (l+r)/2
②递归排序排分别排好左右两侧数据
③归并,即将左右两侧数据合二为一

4、C++代码如下(该代码借鉴AcWing网站模板题):

#include <iostream>

void merge_sort(int q[], int l, int r);

using namespace std;

const int N = 1e6 + 10;

int n, q[N], a[N];//定义一个新数组a[N]用于存放排好的数据

int main()
{
    scanf("%d", &n);//输入需要排几个数
    for (int i = 0; i<n; i++)
    {
        scanf("%d", &q[i]);
    }
    merge_sort(q, 0, n - 1);//引用归并排序函数
    for (int i = 0; i<n; i++)
    {
        printf("%d ", q[i]);
    }
    return 0;
}

void merge_sort(int q[], int l, int r)
{
    if(l >= r) return;
    
    int mid = (r + l) >> 1;//选择终点分界,即(r + l)/ 2
    
    merge_sort(q, l, mid);//递归排左侧数据
    merge_sort(q, mid + 1, r);//递归排右侧数据
    
    int i = l, j = mid + 1, k = 0;//i,j分别指左右侧数据的最小值,k为新数组a[N]的下标
    while (i <= mid && j <= r)
    {
        if (q[i] <= q[j]) a[k++] = q[i++];
        else a[k++] = q[j++];
    }//该循环的作用是比较q[i]和q[j],将较小数存入新数组
    
    while(i <= mid) a[k++] = q[i++];//若左侧数据还未排完,则这些一定是大数,直接依次放入新数组后面
    while(j <= r) a[k++] = q[j++];//若右侧数据还未排完,则这些一定是大数,直接依次放入新数组后面
    
    for (i=l, k=0; i<=r; i++, k++) q[i] = a[k];//因为主函数中用的是q[N]故要将新数组中排好的数据重新存入q[N] 
}
//该代码借鉴AcWing网站模板题

注意事项:
要先用递归排好左右数据,比较时将较小数先存入新数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值