排序算法之桶排序

news2024/11/30 0:44:57

一、桶排序(BucketSort)

桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),最后依次把各个桶中的记录列出来记得到有序序列。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是比较排序,他不受到O(n log n)下限的影响。

1. 基本思想

桶排序的思想近乎彻底的分治思想

桶排序假设待排序的一组数均匀独立的分布在一个范围中,并将这一范围划分成几个子范围(桶)。

然后基于某种映射函数f ,将待排序列的关键字 k 映射到第i个桶中 (即桶数组B 的下标i) ,那么该关键字k 就作为 B[i]中的元素 (每个桶B[i]都是一组大小为N/M 的序列 )。

接着将各个桶中的数据有序的合并起来 : 对每个桶B[i] 中的所有元素进行比较排序 (可以使用快排)。然后依次枚举输出 B[0]….B[M] 中的全部内容即是一个有序序列。

补充: 映射函数一般是 f = array[i] / k; k^2 = n; n是所有元素个数

为了使桶排序更加高效,我们需要做到这两点:

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

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

2. 实现逻辑

  • 设置一个定量的数组当作空桶子。
  • 寻访序列,并且把项目一个一个放到对应的桶子去。
  • 对每个不是空的桶子进行排序。
  • 从不是空的桶子里把项目再放回原来的序列中。

3. 动图演示

桶排序演示

分步骤图示说明:设有数组 array = [63, 157, 189, 51, 101, 47, 141, 121, 157, 156, 194, 117, 98, 139, 67, 133, 181, 13, 28, 109],对其进行桶排序:

4. 复杂度分析

平均时间复杂度:O(n + k)
最佳时间复杂度:O(n + k)
最差时间复杂度:O(n ^ 2)
空间复杂度:O(n * k)
稳定性:稳定

桶排序最好情况下使用线性时间O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为O(n)。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。

5. 代码实现

假设数据分布在[0,100)之间,每个桶内部用链表表示,在数据入桶的同时插入排序。然后把各个桶中的数据合并。

#include<iterator>
#include<iostream>
#include<vector>
using namespace std;
const int BUCKET_NUM = 10;
struct ListNode{
	explicit ListNode(int i=0):mData(i),mNext(NULL){}
	ListNode* mNext;
	int mData;
};
ListNode* insert(ListNode* head,int val){
	ListNode dummyNode;
	ListNode *newNode = new ListNode(val);
	ListNode *pre,*curr;
	dummyNode.mNext = head;
	pre = &dummyNode;
	curr = head;
	while(NULL!=curr && curr->mData<=val){
		pre = curr;
		curr = curr->mNext;
	}
	newNode->mNext = curr;
	pre->mNext = newNode;
	return dummyNode.mNext;
}
ListNode* Merge(ListNode *head1,ListNode *head2){
	ListNode dummyNode;
	ListNode *dummy = &dummyNode;
	while(NULL!=head1 && NULL!=head2){
		if(head1->mData <= head2->mData){
			dummy->mNext = head1;
			head1 = head1->mNext;
		}else{
			dummy->mNext = head2;
			head2 = head2->mNext;
		}
		dummy = dummy->mNext;
	}
	if(NULL!=head1) dummy->mNext = head1;
	if(NULL!=head2) dummy->mNext = head2;
	
	return dummyNode.mNext;
}
void BucketSort(int n,int arr[]){
	vector<ListNode*> buckets(BUCKET_NUM,(ListNode*)(0));
	for(int i=0;i<n;++i){
		int index = arr[i]/BUCKET_NUM;
		ListNode *head = buckets.at(index);
		buckets.at(index) = insert(head,arr[i]);
	}
	ListNode *head = buckets.at(0);
	for(int i=1;i<BUCKET_NUM;++i){
		head = Merge(head,buckets.at(i));
	}
	for(int i=0;i<n;++i){
		arr[i] = head->mData;
		head = head->mNext;
	}
}

三、总结

桶排序是计数排序的变种,它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。把计数排序中相邻的m个”小桶”放到一个”大桶”中,在分完桶后,对每个桶进行排序(一般用快排),然后合并成最后的结果。

算法思想和散列中的开散列法差不多,当冲突时放入同一个桶中;可应用于数据量分布比较均匀,或比较侧重于区间数量时。

桶排序最关键的建桶,如果桶设计得不好的话桶排序是几乎没有作用的。通常情况下,上下界有两种取法,第一种是取一个10^n或者是2^n的数,方便实现。另一种是取数列的最大值和最小值然后均分作桶.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/528046.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[论文阅读] (28)李沐老师视频学习——1.研究的艺术·跟读者建立联系

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0c;非常欢迎大家给我留言评论&#xff0c;学术路上期…

如何成功申请计算机软件著作权【流程完整记录】

致谢 &#xff1a;此博文的编写包括软著的申请&#xff0c;均借鉴了大佬【万里守约】的博客https://blog.csdn.net/qq_45625499/article/details/123463407 提示&#xff1a;此博文仅适合个人申请&#xff0c;因为我是自己一个人的项目&#xff0c;自己一个人申请软著 文章目录…

2023 Android开发者路线-第一部分

2023 Android开发者路线-第一部分 Android 生态系统处于不断发展的状态&#xff1a;每天都会引入新的库和资料&#xff0c;旨在加快开发速度并让我们作为开发人员的生活更轻松。 在这个由多个部分组成的系列中&#xff0c;您将按照我们的2023 年 Android 开发者路线图了解有关…

pyhton GUI编程之Tkinter美化皮肤ttkbootstrap

文章目录 pyhton GUI编程之Tkinter美化皮肤ttkbootstrap介绍 pyhton GUI编程之Tkinter美化皮肤ttkbootstrap介绍 tkinter 相对简单&#xff0c;学习入门很快&#xff0c;但是做出来的GUI界面不够美观&#xff0c;各个组件的外观都很老土&#xff0c;所谓 " 爱美之心&#…

发现一个国产BI软件,做财务数据分析效果绝了

如果是一般的财务数据分析&#xff0c;BI软件们都能做&#xff0c;但如果真要深入了解财务痛点&#xff0c;逐个击破财务数据分析难点&#xff0c;实现多维立体自助式的财务数据分析&#xff0c;那就难。就目前而言&#xff0c;财务数据分析做得好的国产BI软件也就一个奥威BI软…

使用docker构建ElasticSearch集群

目录 一、准备工作 二、编写docker-compose.yml 三、编写ElasticSearch和kibana的配置文件 四、执行构建ElasticSearch集群 五、验证结果&#xff1a; 六、可视化工具 ElasticSearch可视化工具介绍&#xff08;elasticsearch-head、kibana、elasticHD&#xff09; 一、e…

CTF权威指南 笔记 -第四章Linux安全机制-4.1-Stack Canaries

目录 Stack Canaries 简介 我们进行简单的例子 64 32 checksec Stack Canaries 是对抗栈溢出攻击的技术 SSP安全机制 Canary 的值 栈上的一个随机数 在程序启动时 随机生成并且保存在比返回地址更低值 栈溢出是从低地址向高地址进行溢出 如果攻击者要攻击 就一定要覆…

电动力学专题:圆柱形导体中趋肤效应

电动力学分析 金属导体内的电流密度方程 由Maxwell方程组导出Helmhltz方程 对于良导体,有\sigma/(\omega \eprsilon),因此有 圆柱形导线中电流密度分布 设电流沿Z轴方向流动,均匀导体,可简化为 通解&#xff1a; 安培环路定理 定态电磁波的Maxwell方程组 贝塞尔函数性质&…

【SQL】作为前端,应该了解的SQL知识(第三弹)

&#x1f4d1;视图 使用表时&#xff0c;会将数据保存在存储设备&#xff08;硬盘上&#xff09; 而使用视图时&#xff0c;并不会将数据保存在存储设备上&#xff0c;也不会将数据保存在任何地方。 视图里面保存的是 从表中取出数据所使用的SELECT语句&#xff08;视图中的…

zhangrelay博客置顶三篇点击量分析

230515只有三篇置顶&#xff0c;如下&#xff1a; 分别为&#xff1a; 20.03.13 &#xff1a; 901522.01.12 &#xff1a;1372923.04.15 &#xff1a;18836 熟悉zhangrelay博客风格的AI都清楚&#xff0c;他的博客内容都是筛选和设计过的。 置顶三篇阅读量差值为&#xff1…

C++--AVL树的插入,详解四种旋转规则(结尾附源代码链接)

AVL树的插入 前言左单旋右单旋左右双旋右左双旋检查是否这颗树是否是AVL树 前言 AVL树可以说是对二叉搜索树的优化&#xff0c;我们来看二叉树搜索树的下一面一种特殊情况&#xff1a; 当我们插入的数是上面的情况时&#xff0c;二叉树搜索树的特点就形同虚设了&#xff0c;这…

ChatGpt 2步制作流程图与思维导图,你确定不来看一下吗?

什么&#xff1f;你还不会使用ChatGpt。推荐下面这篇文章 ChatGPT保姆级教程&#xff0c;一分钟学会使用ChatGPT&#xff01; - 掘金 (juejin.cn) 如果没有谷歌账号推荐直接买一个&#xff0c;因为你在中国注册谷歌账号&#xff0c;被谷歌查到&#xff0c;也是使用不了ChatGp…

企业数字化转型过程中面临最大的挑战和问题是什么?

无论组织规模如何&#xff0c;业务的敏捷性、弹性以及生产力的高低都是决定其发展运营成功与否的关键因素。而一个良好的数字化转型战略则是企业发展进步的有力助推器。 麦肯锡称&#xff0c;借助数字化转型&#xff0c;可以实现 20% 至 50% 的经济收益和 20% 至 30% 的客户满…

【Spring Cloud Alibaba】Nacos的安装与介绍以及Nacos集群的安装

欢迎来到 Nacos 的世界&#xff01; Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称&#xff0c;一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性…

shell构建基本脚本

构建基本脚本 使用多个命令 一次使用多个命令&#xff0c;把它们放在一行&#xff0c;使用’;隔开 [rootmyserver ~]# date ; who; ls Sun May 14 23:39:34 CST 2023 root pts/0 2023-05-14 23:31 (192.168.10.1) anaconda-ks.cfg initial-setup-ks.cfg创建shel…

JavaScript学习-DOM事件进阶

事件流 事件流和两个阶段说明 事件流指的是事件完整执行过程中的流动路径 说明:假设页面里有个div&#xff0c;当触发事件时&#xff0c;会经历两个阶段&#xff0c;分别是捕获阶段、冒泡阶段 简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父 或者说从大的往下的是捕获&am…

阿里云服务器如何安装宝塔面板?

使用阿里云服务器安装宝塔面板教程&#xff0c;阿里云服务器网以CentOS操作系统为例&#xff0c;安装宝塔Linux面板&#xff0c;先远程连接到云服务器&#xff0c;然后执行宝塔面板安装命令&#xff0c;系统会自动安装宝塔面板&#xff0c;安装完成后会返回面板地址、账号和密码…

前端有必要掌握TypeScript吗,答案十分肯定

本文首发自「慕课网」&#xff08;www.imooc.com&#xff09;&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"或慕课网公众号&#xff01; 作者&#xff1a;一飞同学 | 慕课网讲师 近几年&#xff0c;前端技术发展越来越迅…

亚马逊云科技助力医疗与生命科学行业,提供高性能计算(HPC)

2023年4月27日&#xff0c;亚马逊云科技医疗与生命科学行业峰会召开。会议上&#xff0c;亚马逊云科技大中华区战略业务发展部总经理顾凡表示&#xff1a;“亚马逊云科技不仅提供覆盖全球的云基础设施以及超过200大类的云服务&#xff0c;更重要的是&#xff0c;我们深刻了解行…

Agisoft Metashape 卫星图像处理

Agisoft Metashape 利用卫星图像创建三维模型 文章目录 Agisoft Metashape 利用卫星图像创建三维模型前言一、添加图像二、对齐图像三、构建 DEM四、生成平铺模型前言 Agisoft Metashape Professional 支持处理带RPC参数的立体卫星图像。支持的卫星数据有:Beijing-3A, Ikonos…