十大排序算法-桶排序(c语言实现)

2023-11-04

1.原理

桶排序 (Bucket sort)或所谓的箱排序,是一种分块的排序算法,工作的原理是将数组分到有限数量的桶里,每个桶的大小都相等。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)

把待排序序列(数组)中的数据根据函数映射方法分配到若干个桶中,在分别对各个桶进行排序,最后依次按顺序取出桶中的数据
适用于数据分配均匀,数据比较大,相对集中的情况。

简单来说就是把数据按某种方法分类,每一个类放进一个容器(箱子)中,然后用其他排序方法对每个容器中的数据排序,最后再按分配方法产生的顺序依次取出数据。

2.函数映射 

假设数据都为2或3位的正整数(0~999),那么对应的映射函数可以为

f(x)=x/100        也就是把百位相同的数据都放在同一个容器中,总共有10个容器

映射函数要根据数据情况合理的适用,排序的优劣与函数映射有很大的关系,不同的映射方法就决定了不同的桶的大小以及桶的数量。

极端的方法就是,可以达到每个桶中只有一个元素,使得时间复杂度最优,空间复杂度最高。

函数映射方法的选择要根据具体的情况来选择,没有最好的方法,只有比较合适的方法。

3.排序方法

总的来说有两类实现方法,一类是在把数据从总的容器分配到每一个容器中时就按大小放进去

另一类是把数据全部放入容器中,再来排序。后一类方法可以调用新的排序方法,也可以调用桶排序,形成迭代。

4.代码

我生成了20个3位的随机数(0~999),按照百位的数字分别插入到不同的链表中。

函数映射:        f(x)=x/100        

排序方法:        在从总的数组中分配到每个链表时,按大小插入有序链表

最后按照链表的下标,按顺序取就可以了。

#include <stdio.h>
#include <stdlib.h>
 

typedef struct node {
	int num;	//数据域 
	struct node *next;	//指针域 
}KeyNode;
 
void bucket_sort(int a[],int size,int bucket_size) {
	int i,j;        //数组,数组长度,桶的大小

                        //定义动态的指针数组
	KeyNode **bucket_num = (KeyNode **)malloc(bucket_size * sizeof(KeyNode*));
 
	for(i = 0;i < bucket_size;i++) 
	{
		bucket_num[i] = (KeyNode*)malloc(sizeof(KeyNode));//为每个链表定义头结点 
		bucket_num[i]->num = 0;   
		bucket_num[i]->next = NULL;   //指针变量初始化为空
	}

	for(j = 0;j < size;j++) //准备插入
	{
		KeyNode *node = (KeyNode *)malloc(sizeof(KeyNode));//定义一个节点 
		node->num = a[j];    //数据域存数据 
		node->next = NULL;	//指向空
		
		int index = a[j]/100;  //映射函数 计算桶号
		
		KeyNode *p = bucket_num[index];//p指向链表的头
       
        //链表结构的插入排序
		while(p->next != NULL && p->next->num <= node->num)
		{
			p = p->next;	//1.链表为空,p->next==NULL,进入不了循环 
		}					//2.链表不为空,因为链表从无开始按顺序插入,数据为有序的,
							//可以找到    前一个节点 <= node <=后一个节点
		
		//节点插入链表 
		node->next = p->next;
		p->next = node;
		(bucket_num[index]->num)++;	//记录一下该链表中有几个有效节点 

	}
	//打印结果
	KeyNode * k = NULL;  //定义一个空的结构体指针用于储存输出结果
	for(i = 0;i < bucket_size;i++)
    {
        //for(k = bucket_num[i]->next;k!=NULL;k=k->next)//通过最后一个指针指向空
        k = bucket_num[i]->next;
        for(int m=0;m<bucket_num[i]->num;m++)   //通过头指针记录节点数
        {
            printf("%d ",k->num);
            k=k->next;
        			
    }		
	printf("\n");
}
 
 
int main()
{
	int a[20];
	 
	for(int i=0;i<20;i++)
	{
		a[i]=rand()%1000;	//给数组赋随机数 
		printf("%d ",a[i]);
	}
	puts("");
	puts("");
	//int a[]={491,381,615,917,716,13,217,419,19,138,61,917,176,113,27,419,419,38,615,917,16,113,217,419};
	int size = sizeof(a)/sizeof(int);    //计算数组长度
	bucket_sort(a,size,10);//数组名,数组长度,桶的个数 
   
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

十大排序算法-桶排序(c语言实现) 的相关文章

随机推荐

  • strstr(str1,str2)函数使用 出现问题解析

    定义 strstr str1 str2 函数用于判断字符串str2是否是str1的子串 如果是 则该函数返回str2在str1中首次出现的地址 否则 返回NULL 定义说的有点羞涩难懂 举个例子就知道了 比如 char str2 cdef
  • 学习率与batch-size大小的关系

    近日训练的电脑从一个显卡升级到了4张显卡 这就意味着能够更快的训练速度 但是实际中 并不是这样的 多卡意味着可以使用大点的batch size 这样子会导致每个epoch收敛的更慢了 虽然说速度变快了 但是更新次数变少了 所以收敛的更慢了
  • Java正则表达式Pattern和Matcher

    Java字符串支持使用正则表达式进行替换和分隔操作 字符串提供的正则表达式操作是有限的 比如打印正则表达式匹配到的每一个字符串就无法通过字符串提供的方法来实现 Java使用Pattern和Matcher两个类来支持正则表达式功能 字符串提供
  • java:错误: 找不到符号

    我写了这样一个代码 class Demo public static void main String args int arr 3 5 1 7 2 3 5 6 6 1 8 2 int sum 0 for int x 0 x
  • Llama 2|Meta开源语言模型

    此次 Meta 发布的 Llama 2 模型系列包含 70 亿 130 亿和 700 亿三种参数变体 此外还训练了 340 亿参数变体 但并没有发布 只在技术报告中提到了 据介绍 相比于 Llama 1 Llama 2 的训练数据多了 40
  • 应用层--DNS

    目录 2 4 DNS 域名系统 2 4 1 域名 域名的层级分类 域名的构成 域名管理 2 4 2 域名服务器 DNS 根名字服务器 权威服务器 TLD服务器 本地名字服务器 Local Name Server 名字服务器 Name Ser
  • mysql全局自动提交,MySQL自动提交

    在MySQL中 如果不更改其自动提交变量 则系统会自动向数据库提交结果 用户在执行数据库操作过程中 不需要使用START TRANSACTION语句开始事务 应用COMMIT或者ROLLBACK提交事务或执行回滚操作 如果用户希望通过控制M
  • 绿色经营:从优秀到卓越最显性准则

    关注 实在的力量 郑崇华与台达电的经营智慧 一书 是受 绿色企业家 的启发 绿色企业家 是美国绿色企业标杆英特飞公司的创始人雷C 安德森的自传体管理专著 联想到 从绿到金 等书 我们知道许多美国企业已经从绿色经营中实实在在获利并走上健康的发
  • Unity3D启动时卡在项目Loading界面的解决方法

    问题描述 打开U3D的时候 U3D一直卡在项目选择的界面上 一直显示 Loading 关闭重新开也不行 可能原因 项目配置发生错误 导致无法读取 一直卡Loading 解决方案 1 找到最近一次操作U3D时所加载的项目 一般大概率是这个 如
  • 数字化转型必备:数睿通 2.0 数据中台升级详解

    引言 转眼又过了一个月的时间 数睿通 2 0 数据中台也迎来了本月的更新 本次更新主要包括 数据资产完善 资源评价 数据集市完善 打通审批流程 修复数据生产由于 Druid SQLUtils 不支持 Doris 导致无法建表的问题 优化贴源
  • element-plus dialog #header无效

    这是官方文档的一个坑 来看下官方的案例 他这里使用的是 header来标记title插槽 正确应该是 title 而官网案例打开后也是看不到的自定义的标题内容的 标题这一栏是空白的 而看文档说明也是叫使用的header 这里下面还标注了ti
  • 神秘AI换脸软件入侵全球社交网络!马斯克秒变文艺复兴贵族

    人工智能学习离不开实践的验证 推荐大家可以多在FlyAI AI竞赛服务平台多参加训练和竞赛 以此来提升自己的能力 FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台 每周免费提供项目开源算法样例 支持算法能力变现以及快
  • Vue3中自定义指令监听元素尺寸变化

    vue对元素的宽高变化看了一下 基本都是用的定时器解决的 刚好看到JS的一个属性方法 可以专门监测元素的尺寸变化 MDN地址 https developer mozilla org zh CN docs Web API ResizeObse
  • JSON数据格式解析库(cJSON、Jansson)的使用&在STM32上移植和使用

    json json c使用入门 这篇讲的也不错 抽空看下 网络传输json数据 https www bilibili com video av669454528 p 3 spm id from pageDriver 目录 轻量级C语言JSO
  • 步骤教学 :安装下载Oracle VM VirtualBox + 安装win7 win10镜像文件

    网上一大堆资料 发现搜不到安装镜像文件的步骤 在自己捣鼓完了之后 决定自己写一篇 1 官网下载Oracle VM VirtualBox Downloads Oracle VM VirtualBox 2 安装好Oracle VM Virtua
  • 更改ElementUI默认样式的方法

    1 添加没有scoped的样式 页面中可以有多个 2 有scoped css原生写法 用 gt gt gt gt gt gt 前面可以是父元素或祖先元素 3 项目中用到了scss sass less 都可以使用 deep
  • TCP连接的建立与释放

    一 TCP连接的建立 1 先搭建一个合适的拓扑建立连接 这是一个已经连接好的拓扑 2 PC1 客户端 发送请求建立TCP的请求报文 图为客户端发送的TCP连接建立请求报文 此时的SEQUENCE NUMBER和ACK NUMBER的值均为0
  • 初识服务发现及Consul框架的简单使用

    1 什么是服务发现 服务发现组件记录了 大规模 分布式系统中所有服务的信息 人们或者其它服务可以据此找到这些服务 DNS 就是一个简单的例子 当然 复杂系统的服务发现组件要提供更多的功能 例如 服务元数据存储 健康监控 多种查询和实时更新等
  • 调研:暴恐识别(图像识别)by_xxzcc

    调研 暴恐识别 一 方法 分类 目标检测 人体姿态分析 1 腾讯优图 接口 https ai qq com doc imageterrorism shtml 图片分类 属性 13类 terrorists 恐怖分子 normalarmy 普通
  • 十大排序算法-桶排序(c语言实现)

    1 原理 桶排序 Bucket sort 或所谓的箱排序 是一种分块的排序算法 工作的原理是将数组分到有限数量的桶里 每个桶的大小都相等 每个桶再个别排序 有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序 把待排序序列 数组 中