桶排序算法是“分治法”的典型应用,主要思路是先“分桶”(或建捅)再“合桶”。其中最关键的是“分桶”,这一步最佳的时将整个待排序数组均匀分布在每个“分桶”内,然后再对每个“分桶”内部进行排序,最后将所有排序好的“分桶”依次遍历输出即可。这个思路感觉跟“计数排序算法”和“基数排序算法”十分相识。“计数排序”是通过下标将待排序数映射到“一个桶”内,然后再逐个取出;而“基数排序”是遍历所有“基数”,然后对每个基数进行一轮“计数排序”,最后完成整个数组排序。“桶排序”的“分桶”过程也是需要将待排序元素映射到“桶”内部,故桶分组采用数组,但是“桶”内部一串元素采用链表,目的是为了节省开销,提高效率。

平均时间复杂度为 O(n + m),空间复杂度为 O(n * k),最佳时间复杂度为O(n + m)。

桶排序主要应用在数组均匀分布或者呈现数列分布的情况最适合采用该排序。

一、代码实现分析

下面举一个具体例子。

1.1采用均匀分布方法“分桶”

a1 确定“分桶”个数

假如要对数组arr={ 2,0,1,6,8,10,5,99,87,333,2,0,1 }排序,假设需要桶的个数为bucketNum=std::ceil(size/3),向上取整,反之桶个数不够映射时跑死越界。

if (nums.size() <= 1)
return;
auto minmax = std::minmax_element(nums.begin(), nums.end()); // a1 确定“分桶”个数
int min = *minmax.first;
int max = *minmax.second;
int bucketNum = std::ceil(nums.size() * 1.0 / 3); // 假设桶个数有这么多个,实际最优取值需要根据具体数组给定
vector<list<int>> bucket(bucketNum);

a2  确定桶间距gap

先找出最值,然后得出每个桶间距,即gap=(max-min)/bucketNum;此处考虑异常,假如gap==0则直接返回;

int gap = std::ceil((max - min) * 1.0 / bucketNum); // 每个桶间距,假设均匀分布
if (gap == 0) // 如果最大值等于最小值所以都是一样的元素不需要排序
return;
int index = 0;

a3  将待排序数组元素尽可能均匀依次映射入每个“分桶”

for (const auto& it : nums) // a2  将待排序数组元素尽可能均匀依次映射入每个“分桶”
{int index = (it - min) / gap; // 确定待排序数落在哪个分桶内,间隔长度/间距,取整后截断后面小数,左边闭区间bucket[index].push_back(it);
}

a4  对每个分桶依次进行排序

for (auto& it : bucket) // a3  对每个分桶依次进行排序it.sort();

a5  “合桶”,遍历每个“分桶”并依次输出“分桶”排序后的元素

for (const auto& it : bucket) // a4  “合桶”,遍历每个“分桶”并依次输出“分桶”排序后的元素
{for (const auto& iter : it){nums[index] = iter;++index;}
}

1.2完整代码

Sorts.h

#pragma once#include <iostream>
#include <vector>using namespace std;struct Sorts {    void bucket(vector<int>& nums);    void print(vector<int>& nums);
};

Sorts.cpp

#include "Sorts.h"
#include <list>
#include <algorithm>void Sorts::bucket(vector<int>& nums)
{    if (nums.size() <= 1)return;auto minmax = std::minmax_element(nums.begin(), nums.end()); // a1 确定“分桶”个数int min = *minmax.first;int max = *minmax.second;int bucketNum = std::ceil(nums.size() * 1.0 / 3); // 假设桶个数有这么多个,实际最优取值需要根据具体数组给定vector<list<int>> bucket(bucketNum);int gap = std::ceil((max - min) * 1.0 / bucketNum); // 每个桶间距,假设均匀分布if (gap == 0) // 如果最大值等于最小值所以都是一样的元素不需要排序return;int index = 0;for (const auto& it : nums) // a2  将待排序数组元素尽可能均匀依次映射入每个“分桶”{int index = (it - min) / gap; // 确定待排序数落在哪个分桶内,间隔长度/间距,取整后截断后面小数,左边闭区间bucket[index].push_back(it);}    for (auto& it : bucket) // a3  对每个分桶依次进行排序it.sort();for (const auto& it : bucket) // a4  “合桶”,遍历每个“分桶”并依次输出“分桶”排序后的元素{for (const auto& iter : it){nums[index] = iter;++index;}}
}void Sorts::print(vector<int>& nums)
{for (const auto& it : nums)cout << it << ",";cout << endl;
}

main.cpp

 #include <vector>
#include "Sorts.h"using namespace std;int main()
{vector<int> nums = { 2,0,1,6,8,10,5,99,87,333,2,0,1 };Sorts sorts;sorts.print(nums);sorts.bucket(nums);sorts.print(nums);return 1;
}

1.3输出结果

桶排序算法——C++相关推荐

  1. 桶排序算法(基于Java实现)

    title: 桶排序算法(基于Java实现) tags: 桶排序算法 桶排序算法的原理和代码实现 一.桶排序算法的原理 桶排序,顾名思义,会用到"桶",核心思想是将要排序的数据分到 ...

  2. php桶排序,PHP实现桶排序算法

    本篇讲解PHP实现桶排序算法. 简单意义上的桶排序: 桶排序的原理是先安排N+1个桶作为容器,若数据范围为N的话. 然后将测试数据(所需排序的数据)进行循环,放入对应的桶内.数据一定是在范围N内的. ...

  3. 十大经典排序算法-桶排序算法详解

    十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...

  4. 【每日算法】桶排序算法

    1)算法简介 桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里.每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序 ...

  5. 经典排序算法(9)——桶排序算法详解

    桶排序(Bucket sort)或所谓的箱排序,并不是比较排序,它不受到 O(nlogn) 下限的影响. 一.算法基本思想 (1)基本思想 桶排序工作的原理是将数组分到有限数量的桶子里,每个桶子再个别 ...

  6. 桶排序算法:topK元素golang实现

    首先介绍一下桶思想: 在现实世界中,大部分的数据分布是均匀的,或者在设计的时候让它可以均匀分布,或者说可以转换为均匀的分布. 数据均匀分布了,桶排序的效率就能发挥出来.(分库分表) 误区:    1. ...

  7. 桶排序算法——C/C++

    桶排序 1. 算法思想 桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里,每个桶再分别排序(大部分是在分桶时,即插入时就排序了). 个人理解,适合数 ...

  8. 帮我写一个桶排序算法

    桶排序是一种线性排序算法.它的基本思路是将数据分别放入不同的桶中,然后对每个桶内部进行排序,最后将每个桶内排好序的数据拼接起来. 下面是桶排序的具体步骤: 设置固定数量的空桶. 遍历待排序数组,将每个 ...

  9. 桶式排序 php,PHP实现桶排序算法

    简单意义上的桶排序: 桶排序的原理是先安排N+1个桶作为容器,若数据范围为N的话. 然后将测试数据(所需排序的数据)进行循环,放入对应的桶内.数据一定是在范围N内的. 最后,循环桶里的元素,并且输出, ...

最新文章

  1. SQL2K数据库开发二之查看和修改Sample数据库
  2. 多线程总结五:线程通信(一)
  3. 35个设计一流的美味的水果壁纸欣赏
  4. c++ 编译添加dll_linux下编写C/C++代码须知———串讲
  5. free 命令查看linux的内存使用情况
  6. PoPo数据可视化第8期
  7. Allocate aligned memory
  8. 毕业后半年就变成了一条“狗
  9. VMware运维工程师常用工具介绍
  10. 关于部分网页打不开的解决方法详解
  11. 泡泡龙游戏开发系列教程(六)
  12. destoon网站转移空间教程
  13. Wireshark网络分析实战笔记(二)显示过滤器
  14. 电脑使用者的眼睛保护
  15. 如何快速把旧电脑数据转移到新电脑?
  16. Android平板怎么截屏,ipad mini怎么截图 iPad/iPad mini截图技巧图解
  17. 表白墙源码/可用作博客论坛都是不错的
  18. 疫情查询 国内疫情显示“无网络”解决方法
  19. 一到面试就紧张,该怎么办?
  20. 基于vue的仿饿了么webapp

热门文章

  1. 金蝶k3怎么显示服务器地址,金蝶k3如何查询连接的服务器配置
  2. android抖音切换实现,【Android 进阶】仿抖音系列之视频预览和录制(五)
  3. 仿抖音短视频录制按钮动画
  4. 朗科实习期间心得笔记(五)
  5. 基于jsp+mysql+ssm网络硬硬盘系統网站-计算机毕业设计
  6. 投影仪推荐那种好?什么牌子投影仪比较好
  7. 游戏攻略:《刺客信条:启示录》通关感想和对刺客信条3展望
  8. 今日简报 每日精选12条新闻简报 每天一分钟 知晓天下事 2月23日
  9. python 遍历是什么意思_python for语句的执行过程是什么
  10. 多人联机射击游戏中的设计模式应用