基数排序详解

目录

一、桶排序思想

1.1 什么是桶排序

1.2 桶排序的步骤

二、基数排序思想

2.1 什么是基数排序

2.2 实现方式

2.3 图解

三、代码思路

3.1 前置工作

3.2 映射

3.3 排序

四、C语言源码


一、桶排序思想

1.1 什么是桶排序

桶排序(Bucket sort)是一种排序算法,它将要排序的数据分到有限数量的桶中,然后对每个桶进行单独排序,最后将所有的桶合并在一起得到排好序的数据。

简而言之,就是把待排序序列(数组)中的数据根据某种函数映射方法分配到若干个桶中,在分别对各个桶进行排序,最后依次按顺序取出桶中的数据。

本文介绍的基数排序就是函数映射的方法之一。

1.2 桶排序的步骤

  1. 首先确定桶的数量和范围,然后将数据分配到对应的桶中。
  2. 对每个桶中的数据进行排序,可以使用其他排序算法比如插入排序或者快速排序。
  3. 最后将所有桶中的数据按照顺序合并,就得到了排好序的数据。

二、基数排序思想

2.1 什么是基数排序

基数排序是一种分配式排序算法,它根据数据的每一位数字来排序,从最低位开始,依次对位数进行排序。基数排序的具体步骤如下:

  1. 根据待排序的数据确定最大位数,用来确定排序的轮数
  2. 将所有待排序的数据统一为同样的位数,不足位数的在前面补0。
  3. 从最低位开始,将数据分配到0-9的10个中,根据当前位的数字进行分配。
  4. 将数据按照桶的顺序依次合并,然后增加一位进行下一轮分配和合并,直至所有位均排完,得到排好序的数据。

2.2 实现方式

  • 最低位优先法(LSD):从最低位排到最高位
  • 最高位优先法(MSD):从最高位排到最低位

2.3 图解

三、代码思路

3.1 前置工作

  • 求解最高位数
//获取最大位数
int _GetMaxBit(int* array, int size)
{
	int bit = 1;
	int max = 10;
	for (int i = 0; i < size; ++i)
	{
		while (array[i] >= max)
		{
			max *= 10;
			bit++;
		}
	}
	return bit;
}
  • 开辟拷贝数组
//创建桶数组
int* bucket = (int*)malloc(sizeof(int) * size);
if (bucket == NULL)
{
	perror("malloc");
	exit(1);
}
memset(bucket, 0, sizeof(int) * size);

3.2 映射

类似于计数排序的思想,将每一位出现的次数都映射到数组中。

与计数排序不同的点是,需要存入当前的值,也是实现的难点。介绍两个思路

  • 直接存入
  1. 采用二维数组:行数为10,对应0~9;列数为数组大小,存有符合当前位数的值。缺点是空间浪费巨大。
  2. 采用队列:数组存的元素是队列,直接压入队列就可以。解决了二维数组空间浪费太多的问题,缺点是C语言需要自己编写队列的底层代码
  • 获取在桶数组的位置

本方法是本文推荐实现的代码。通过两个数组存储每个值在桶数组的索引位置。这样可以将数据最后都存到一个数组中,可以极大简化后序遍历的操作。

//计数数组
int count[10] = { 0 };
//位置索引数组
int index[10] = { 0 };
  • 计数数组:类似于基数排序,计算每一位出现多少次
    // 确定对应位桶数据的个数
    for (int i = 0; i < size; ++i)
    {
    	//取出某一位
    	int k = (array[i] / radix) % 10;
    	//对应索引位++
    	count[k]++;
    }
  • 索引数组:记录的是每一位第一次出现的数据在桶数组中的下标。因为总体的数据是一定的,所以获取后序数组的位置只需要加一。

桶数组中的第一个数下标一定是0

某一位的第一个元素就是 索引数组的前一个值 加上 计数数组对应位的值

// 确定在桶中的位置
for (int i = 1; i < 10; ++i)
{
	index[i] = index[i - 1] + count[i - 1];
}

3.3 排序

  • 单次
  1. 创建索引
  2. 把数据按照下标索引重新排序到桶数组中
  3. 将桶数组的数据拷贝回原数组
  • 循环(以LSD为例)
  1. 位数从个位开始每次增加直到退出循环
  2. 每次进入新循环,两个数组的值都需要置零

四、C语言源码

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include<string.h>

//获取最大位数
int _GetMaxBit(int* array, int size)
{
	int bit = 1;
	int max = 10;
	for (int i = 0; i < size; ++i)
	{
		while (array[i] >= max)
		{
			max *= 10;
			bit++;
		}
	}
	return bit;
}
//基数排序-LSD
void RadixSort_LSD(int* array, int size)
{
	//获取最高位数
	int maxBit = _GetMaxBit(array, size);
	//创建桶数组
	int* bucket = (int*)malloc(sizeof(int) * size);
	if (bucket == NULL)
	{
		perror("malloc");
		exit(1);
	}
	memset(bucket, 0, sizeof(int) * size);

	//计数数组
	int count[10] = { 0 };
	//位置索引数组
	int index[10] = { 0 };

	int radix = 1;
	for (int bit = 1; bit <= maxBit; ++bit)
	{
		memset(count, 0, sizeof(int) * 10);
		memset(index, 0, sizeof(int) * 10);

		// 确定对应位桶数据的个数
		for (int i = 0; i < size; ++i)
		{
			//取出某一位
			int k = (array[i] / radix) % 10;
			//对应索引位++
			count[k]++;
		}
		// 确定在桶中的位置
		for (int i = 1; i < 10; ++i)
		{
			index[i] = index[i - 1] + count[i - 1];
		}
		// 将数据放到对应的桶中
		for (int i = 0; i < size; ++i)
		{
			//取出某一位
			int k = (array[i] / radix) % 10;
			//放入桶中
			bucket[index[k]++] = array[i];
		}
		// 将桶中排后数据拷贝回原数组
		memcpy(array, bucket, sizeof(int) * size);

		radix *= 10;
	}
	free(bucket);
	bucket = NULL;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络安全课程开发

我们为卡巴斯基实验室开发了一个交钥匙教育门户网站&#xff0c;并为其开设了网络安全课程。在资源上&#xff0c;你可以熟悉课程的理论部分-观看视频或阅读插图文本版本&#xff0c;然后通过回答问题来验证你的知识。通过最终测试后&#xff0c;用户将获得证书。 对于这个项目…

Pythone 程序打包成 exe

1.安装pyinstaller # 安装 pip install pyinstaller # 查看版本 pyinstaller -v2.更新pyinstaller 版本 # 更新 pip install --upgrade pyinstaller # 查看版本 pyinstaller -v3.切换到 py文件所在目录 #切换到.py所在的目录 E: cd cd E:\x-svn_x-local\04PythoneProjects\A…

平安养老险陕西分公司荣获“2021-2023年乡村振兴‘三村工程’先进机构”

5月27日&#xff0c;中国平安成立36周年司庆暨三省推广启动大会顺利召开。会上&#xff0c;平安养老险陕西分公司获“2021-2023年乡村振兴‘三村工程’先进机构”荣誉表彰。 过去三年间&#xff0c;平安养老险陕西分公司始终坚持金融为民&#xff0c;在平安集团、平安养老险的指…

【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【08】【商品服务】Object划分_批量删除

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【08】【商品服务】Object划分_批量删除 Object划分批量删除/添加参考 Object划分 数据库中对于一张表的数据&#xff0c;由于拥有隐私字段、多余字段、字段过少等原因&#xff0c;不应该直…

33 _ 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

通过上篇文章的介绍&#xff0c;我们知道了同源策略可以隔离各个站点之间的DOM交互、页面数据和网络通信&#xff0c;虽然严格的同源策略会带来更多的安全&#xff0c;但是也束缚了Web。这就需要在安全和自由之间找到一个平衡点&#xff0c;所以我们默认页面中可以引用任意第三…

js之简单轮播图

今天给大家封装一个简单的轮播图,可以点击下一张上一张以及自动轮播 <!DOCTYPE html> <html><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>走马…

基于蚁群算法的二维路径规划算法(matlab)

微♥关注“电击小子程高兴的MATLAB小屋”获得资料 一、理论基础 1、路径规划算法 路径规划算法是指在有障碍物的工作环境中寻找一条从起点到终点、无碰撞地绕过所有障碍物的运动路径。路径规划算法较多&#xff0c;大体上可分为全局路径规划算法和局部路径规划算法两大类。其…

Neo4j 桌面版打不开踩坑贴

真的踩坑。。。没有人告诉我为啥桌面版和社区版不能一起下啊&#xff01;&#xff01; 我是先下载了社区版之后再下载的桌面版&#xff0c;结果桌面版界面一直打不开。 尝试了网上多种办法都没效果&#xff0c;好多都是说jdk不兼容导致无法打开&#xff0c;让我从JDK 17 ->…

跨域、JSONP、CORS、Spring、Spring Security解决方案

概述 JavaScript出于安全方面的考虑&#xff0c;不允许跨域调用其他页面的对象。跨域是浏览器&#xff08;如Chrome浏览器基于JS V8引擎&#xff0c;可以简单理解为JS解释器&#xff09;的一种同源安全策略&#xff0c;是浏览器单方面限制脚本的跨域访问。因此&#xff0c;仅有…

python使用wkhtmltopdf将html字符串保存pdf,解决出现方框的问题

出现的问题: 解决办法: <html> <head><meta charset="UTF-8"/> </head> <style> * {font-family: Arial,SimSun !important; } </style> </html>在html字符串前面加上上面代码,意思是设置字体编码和样式 html示例:…

足球实况分析系统YOLO

① 足球运动员、裁判和球检测&#xff1b; ② 球员球队预测&#xff1b; ③ 足球地图上球员和球位置的估计&#xff1b; ④ 足球跟踪&#xff1b; 当你启动应用程序时&#xff0c;会自动加载两个演示视频以及推荐的设置和超参数. 1. 使用侧栏菜单“浏览文件”按钮上传视频…

【Linux系统编程】进程终止

目录 strerror函数 errno错误码 退出码 正常终止&#xff08;可以通过 echo $? 查看进程退出码&#xff09;&#xff1a; 1. 从main返回&#xff08;return&#xff09; 2. 调用exit 3. _exit&#xff08;一般尽量不要用&#xff09; 异常退出&#xff1a; ctrl c&am…

瓦片边界可视化工具

本文涉及的核心内容 瓦片边界可视化-VisibleTileBoundariesmeethigher/visible-tile-boundaries: visible tiles boundaries demo 一、瓦片边界可视化 1.1 背景 日常GIS开发中&#xff0c;需要了解瓦片是什么&#xff0c;瓦片展示的效果是什么样的。这种口头上抽象的东西&a…

惊艳的短视频:成都科成博通文化传媒公司

惊艳的短视频&#xff1a;瞬间之美&#xff0c;震撼心灵 在数字化时代&#xff0c;短视频以其短小精悍、内容丰富的特点&#xff0c;迅速占领了我们的屏幕和时间。而在这个浩如烟海的视频海洋中&#xff0c;总有一些短视频能够脱颖而出&#xff0c;以其惊艳的视觉效果、深刻的…

您对薪资待遇是否满意?没证据怎么办?这样做很可能会补上来!

您对薪资待遇是否满意&#xff1f;没证据怎么办&#xff1f; 这样做很可能会补上来&#xff01; 您有时可能对自己的工资或福利待遇感到不满意&#xff1a;感到为何我付出的不比别人少&#xff0c;但是工资待遇总是比别人低&#xff0c;是不是觉得很不服气&#xff1f;那么不服…

【技巧】让xorg和gnome不要使用GPU

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 默认xorg会使用GPU加速&#xff1a; 现在取消他对GPU的占用&#xff1a; sudo vim /etc/X11/xorg.conf修改或添加以下内容&#xff1a; Section &quo…

迁移学习助力机器学习实践应用

大家好&#xff0c;迁移学习是一种技术&#xff0c;能使机器利用从以前任务中获得的知识来提高对新任务的泛化能力。作为ChatGPT和Google Gemini等模型的核心原理&#xff0c;迁移学习在长文档总结、复杂文章撰写、旅行规划以及诗歌和歌曲创作等重要任务中发挥着关键作用。 本…

ArcGIS+SWAT+CENTURY:流域生态系统水-碳-氮耦合过程模拟

目录 章节一 流域水碳氮建模-概述 章节二 数据准备 章节三 流域水模拟 章节四 流域氮模拟 章节五 流域碳模拟 章节六 模型结果分析及地图制作 章节七 案例分析 更多应用 流域是一个相对独立的自然地理单元&#xff0c;它是以水系为纽带&#xff0c;将系统内各自然地理要…

verilog阻塞和非阻塞语法

阻塞和非阻塞是FPGA硬件编程中需要了解的一个概念,绝大部分时候,因为非阻塞的方式更加符合时序逻辑设计的思想,有利于时钟和信号的同步,更加有利于时序收敛,所以除非特殊情况,尽量采用非阻塞方式。 1,非阻塞代码 非阻塞赋值,A和B是同时被赋值的,具体是说在时钟的上升…

设计模式-享元模式(结构型)

享元模式 享元模式是一种结构型模式&#xff0c;它主要用于减少创建对象的数量&#xff0c;减少内存占用。通过重用现有对象的方式&#xff0c;如果未找到匹配对象则新建对象。线程池、数据库连接池、常量池等池化的思想就是享元模式的一种应用。 图解 角色 享元工厂&#xf…