2023/11/25 直方图(桶排序)

12 篇文章 0 订阅

如果这个题用普通的做法挺难想的:又要找到最大值,又要给每个值计出现次数。但是有计数排序思想就变得很简单。

我们不直接存储数,而是把数当成下标,放进一个桶(一般是一个很大的数组)中。

比如现在有一个桶数组 F[10000],它可以存储 0−100000−10000 的数,然后我们从 0−100000−10000 输出,如果桶非空,就输出现在循环到的下标,这样输出一定是有序的,因为下标是绝对按照顺序来排列的。

 需要注意的是,注意桶的数据范围不是n而是输入的数最大为多少。

#include<iostream>

using namespace std;

int main()
{
	int arr[100000] = { 0 };
	int n;
	cin >> n;
	int x;
	int max = 0;
	for (int i = 0; i < n; i++)
	{
		cin >> x;
		arr[x]++;
		max = (max > x ? max : x);
	}
	for (int i = 0; i <= max; i++)
	{
		cout << arr[i] << endl;
	}

	return 0;
}

/* 计数排序 */
// 简单实现,无法用于排序对象
void countingSortNaive(vector<int> &nums) {
    // 1. 统计数组最大元素 m
    int m = 0;
    for (int num : nums) {
        m = max(m, num);
    }
    // 2. 统计各数字的出现次数
    // counter[num] 代表 num 的出现次数
    vector<int> counter(m + 1, 0);
    for (int num : nums) {
        counter[num]++;
    }
    // 3. 遍历 counter ,将各元素填入原数组 nums
    int i = 0;
    for (int num = 0; num < m + 1; num++) {
        for (int j = 0; j < counter[num]; j++, i++) {
            nums[i] = num;
        }
    }
}

注意看这个:11.9   计数排序 - Hello 算法 (hello-algo.com)icon-default.png?t=N7T8https://www.hello-algo.com/chapter_sorting/counting_sort/#1193


「桶排序 bucket sort」是分治策略的一个典型应用。它通过设置一些具有大小顺序的桶,每个桶对应一个数据范围,将数据平均分配到各个桶中;然后,在每个桶内部分别执行排序;最终按照桶的顺序将所有数据合并。 

/* 桶排序 */
void bucketSort(vector<float> &nums) {
    // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
    int k = nums.size() / 2;
    vector<vector<float>> buckets(k);
    // 1. 将数组元素分配到各个桶中
    for (float num : nums) {
        // 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
        int i = num * k;
        // 将 num 添加进桶 bucket_idx
        buckets[i].push_back(num);
    }
    // 2. 对各个桶执行排序
    for (vector<float> &bucket : buckets) {
        // 使用内置排序函数,也可以替换成其他排序算法
        sort(bucket.begin(), bucket.end());
    }
    // 3. 遍历桶合并结果
    int i = 0;
    for (vector<float> &bucket : buckets) {
        for (float num : bucket) {
            nums[i++] = num;
        }
    }
}

 注意看这个:11.8   桶排序 - Hello 算法 (hello-algo.com)icon-default.png?t=N7T8https://www.hello-algo.com/chapter_sorting/bucket_sort/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值