桶排序

题目描述

给你 n(2n106)n(2\le n\le10^6) 个数,a1,a2,a3,,ana_1,a_2,a_3,\dots ,a_n

每个数字 aia_i 范围为 0ai1040\le a_i \le 10^4。 将他们从大到小排序,然后输出。

输入格式

共两行,第一行为一个整数 nn

第二行为 nn 个数字,a1,a2,,ana_1,a_2,\dots,a_n

输出格式

共一行,为 nn 个从大到小的数字。

样例 #1

样例输入 #1

1
2
5
6 7 1 2 2

样例输出 #1

1
7 6 2 2 1

提示

对于 100% 的测试数据

2n1062\le n\le10^60ai1040\le a_i \le 10^4

根据你提供的题意描述,问题的核心在于对 nn 个范围在 0 到 10000 之间的整数进行从大到小的排序。题目数据量大(最多 10610^6 个数),需要高效的排序算法,桶排序是一个合适的选择。

为了保证代码能够处理最大规模的数据,以下是经过修正和优化后的桶排序实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std;

int n, a[10001]; // 桶数组大小为10001,涵盖从0到10000的所有可能值

int main() {
ios::sync_with_stdio(false); // 关闭同步,加速输入输出
cin.tie(nullptr); // 解除cin与cout的绑定,加速输入输出

cin >> n; // 读取数字个数

// 初始化桶数组
for(int i = 0; i <= 10000; i++) {
a[i] = 0;
}

// 读取输入数据并计数
for(int i = 0; i < n; i++) {
int x;
cin >> x;
a[x]++;
}

// 输出排序结果,从大到小
for(int i = 10000; i >= 0; i--) {
for(int j = 0; j < a[i]; j++) {
cout << i << ' ';
}
}
cout << endl;
return 0;
}

代码解释

  1. 输入输出优化

    1
    2
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    这些行代码用于加速输入输出操作,尤其是在处理大数据量时非常重要。

  2. 桶数组声明

    1
    int n, a[10001];

    数组 a 的大小设置为 10001,以涵盖所有可能的数值(0到10000)。

  3. 初始化桶数组

    1
    2
    3
    for(int i = 0; i <= 10000; i++) {
    a[i] = 0;
    }

    初始化所有桶的计数为0。

  4. 读取输入数据并计数

    1
    2
    3
    4
    5
    for(int i = 0; i < n; i++) {
    int x;
    cin >> x;
    a[x]++;
    }

    遍历输入的 n 个数,每个数对应的桶的计数加一。

  5. 输出排序结果

    1
    2
    3
    4
    5
    for(int i = 10000; i >= 0; i--) {
    for(int j = 0; j < a[i]; j++) {
    cout << i << ' ';
    }
    }

    遍历桶数组,从大到小输出每个桶中的数值,每个数值根据桶的计数输出相应次数。

运行示例

给定输入:

1
2
5
6 7 1 2 2

输出结果:

1
7 6 2 2 1

性能分析

由于题目要求处理的数据量很大(最多 10610^6 个数),桶排序在这类情况下表现非常好。桶排序的时间复杂度为 O(n+k)O(n + k),其中 nn 是输入数据的数量,kk 是桶的数量。在这里,桶的数量 k=10001k = 10001,所以总体时间复杂度非常接近线性时间,适合处理大规模数据。

通过这些调整和优化,这段代码能够有效地满足题目要求,对大数据量进行高效的排序。