C++入门 桶排序

1.桶排序基本介绍

桶排序是计数排序的升级版。其实桶排序从字面意思上就很好理解,首先肯定和桶是离不开关系的,分成若干个桶,每个桶对应不同的区间,把待排序的数字分别放入相应的桶里面,每个桶里面的数字在进行一次排序(排序方式自己决定),排序结束后,再依次把每个桶的数字打印出来,桶排序就完成了。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

  1. 在额外空间充足的情况下,尽量增大桶的数量
  2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

2.算法思想

桶排序思想就是把区间划分为n个大小相同的子区间,这样的子区间称为桶。然后将区间的每个元素按区间范围分到各个桶中去。每一个桶再分个排序,然后按照次序把每个桶中的元素依次取出来,就能把区间排完序。桶排序的时间复杂度和空间复杂度都是O(n),桶排序是一种稳定的排序算法。但是桶排序的性能并非是绝对稳定的,因为如果元素分布不均衡,比如说创建了100个桶,大多数元素都集中在了第1个桶,这样桶排序的时间复杂度就会退化为O(n logn),而且还浪费了空间。

3.示意图

元素分布在桶中:

然后,元素在每个桶中排序:

4.性能分析 

时间复杂度:O(N + C),C=N*(logN-logM)

对于待排序序列大小为 N,共分为 M 个桶,主要步骤有:

N 次循环,将每个元素装入对应的桶中

M 次循环,对每个桶中的数据进行排序(平均每个桶有 N/M 个元素)

一般使用较为快速的排序算法,时间复杂度为 O(NlogN),实际的桶排序过程是以链表形式插入的。

整个桶排序的时间复杂度为:

O(N)+O(M∗(N/M∗log(N/M)))  = O(N)+O(N∗(log(N/M)) = O(N)+O(C)= O(N∗(log(N/M)+1))

当 N = M 时,复杂度为 O(N)

额外空间复杂度:O(N + M)

5.代码实现

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void bucketSort(vector<int>& arr, int maxVal) {
    int n = arr.size();
    vector<vector<int>> buckets(maxVal + 1);

    // 将元素分配到桶中
    for (int i = 0; i < n; ++i) {
        int bucketIndex = arr[i];
        buckets[bucketIndex].push_back(arr[i]);
    }

    // 对每个桶中的元素进行排序
    for (int i = 0; i <= maxVal; ++i) {
        sort(buckets[i].begin(), buckets[i].end());
    }

    // 合并所有桶的元素
    int index = 0;
    for (int i = 0; i <= maxVal; ++i) {
        for (int j = 0; j < buckets[i].size(); ++j) {
            arr[index++] = buckets[i][j];
        }
    }
}
int main() {
    vector<int> arr = { 300, 26,38, 2, 111,111, 112, 7 };
    //max_element()是一个标准库函数,搜寻向量arr,返回了一个最大值迭代器,用*解引用出迭代器的数值
    int maxVal = *max_element(arr.begin(), arr.end());

    cout << "原始数组:" <<endl;
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    bucketSort(arr, maxVal);

    cout << "排序后的数组:" << endl;
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值