桶排序及C语言实现

本文内容主要参考这篇博文:http://hxraid.iteye.com/blog/647759

桶排序算法的基本原理是:把数组中的所有元素分为若干个数据块,也就是若干个桶,然后对每个桶里的数据进行排序,最后将所有桶里的数据依次排列即可。

这里就存在两个问题:

(1)怎样划分数据块,也就是分几个桶,每个桶放哪几个数据。

(2)对每个数据块里的数据怎样排序。

对于第一个问题:用函数映射的方法来划分。举一个很简单的例子,假设数据都为2位的正整数,那么对应的映射函数可以为f(x)=x/10.即把十位相同的数划到同一数据块。如下图所示。

对于第二个问题:用前面讲的排序算法对每个数据块的元素进行排序即可,比如插入排序,快速排序等。

同样,对于算法时间复杂度的分析,也是基于上面两个问题的影响。对数组进行划分数据块,时间复杂度为O(n),对每个数据块进行排序,时间复杂度取决于使用的排序算法。在极致情况下,每个桶只有一个数据,这样的时间复杂度无疑是最优的,因为每个数据块不需要进行排序。但是空间复杂度太高。

总之,桶排序的思想就是,将数组中的全部元素划分成若干个数据块,并对每个数据块分别进行排序,以此提高时间复杂度。该算法主要适合于数量比较大并且数字相对比较集中的场合。下面是代码。

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

typedef struct node {
	int key;
	struct node *next;
}KeyNode;

void bucket_sort(int keys[],int size,int bucket_size) {
	int i,j;
	KeyNode **bucket_table = (KeyNode **)malloc(bucket_size * sizeof(KeyNode*));
	for(i = 0;i < bucket_size;i++) {
		bucket_table[i] = (KeyNode*)malloc(sizeof(KeyNode));
		bucket_table[i]->key = 0;
		bucket_table[i]->next = NULL;
	}
	for(j = 0;j < size;j++) {
		KeyNode *node = (KeyNode *)malloc(sizeof(KeyNode));
		node->key = keys[j];
		node->next = NULL;
		int index = keys[j]/10;
		KeyNode *p = bucket_table[index];
		if(p->key == 0) {
			bucket_table[index]->next = node;
			(bucket_table[index]->key)++;
		}else {
			while(p->next != NULL && p->next->key <= node->key)
				p = p->next;
			node->next = p->next;
			p->next = node;
			(bucket_table[index]->key)++;
		}
	}
	//print result
	KeyNode * k = NULL;
	for(i = 0;i < bucket_size;i++)
		for(k = bucket_table[i]->next;k!=NULL;k=k->next)
			printf("%d ",k->key);
	printf("\n");
}

int main()
{
	int raw[] = {49,38,65,97,76,13,27,49};
	int size = sizeof(raw)/sizeof(int);
	bucket_sort(raw,size,10);
}
时间: 2024-11-11 00:40:36

桶排序及C语言实现的相关文章

C语言学习之桶排序

之前的博文写了交换(冒泡)排序.选择排序,本文就写写桶排序.不过我理解的这样不算是真正上的桶排序,我的比较简单而真正的桶排序是比较复杂的,暂且就叫桶排序吧. 桶排序在排序中应该用的不多吧,个人理解的是比较简单易懂的,针对小量数据的排序很有用,不过有个小缺点就是只适合在屏幕上打印输出,实际的应用中我们是利用这样排列好之后的数据,我想这就是桶排序应用场合比较少的原因吧. 就简单讲讲吧,故名思意 桶排序就是一排带有序列编号的的桶子,而这编号的范围就是将我们要排序数据包括在内.在我们输入数据的时会在与输

计数排序、桶排序python实现

计数排序在输入n个0到k之间的整数时,时间复杂度最好情况下为O(n+k),最坏情况下为O(n+k),平均情况为O(n+k),空间复杂度为O(n+k),计数排序是稳定的排序. 桶排序在输入N个数据有M个桶时,如果每个桶的数据接近N/M个且桶内使用基于比较的排序,则桶排序的时间复杂度为O(N+M*N/M*log(N/M)).如果N=M时,每个桶只有一个数据,时间复杂度降低为O(N). 桶排序的时间复杂度为O(N+M),桶排序是稳定的排序 1.计数排序 计数排序介绍及C语言实现在:计数排序(链接) d

排序算法之——桶排序

这是本人的第一篇随笔,为的是分享学习经验,和大家讨论一些算法,以便取得些许进步,也是对学习的总结. 话不多说,下面我会用图文的方式向各位介绍桶排序. 1.主要思想: 桶排序的大体思路就是先将数组分到有限个桶中,再对每个桶中的数据进行排序,可以说是鸽巢排序的一种归纳结果(对每个桶中数据的排序可以是桶排序的递归,或其他算法,在桶中数据较少的时候用插入排序最为理想). 2.算法效率: 对N个数据进行桶排序的时间复杂度分为两部分: 1.对每一个数据进行映射函数的计算(映射函数确定了数据将被分到哪个桶),

【算法】计数排序、桶排序和基数排序详解

01.计数排序.桶排序与基数排序 并不是所有的排序 都是基于比较的,计数排序和基数排序就不是.基于比较排序的排序方法,其复杂度无法突破\(n\log{n}\) 的下限,但是 计数排序 桶排序 和基数排序是分布排序,他们是可以突破这个下限达到O(n)的的复杂度的. 1. 计数排序 概念 计数排序是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C,使用 C[i] 来计算 i 出现的次数.然后根据数C来将原数组A中的元素排到正确的位置. 复杂度 计数排序的最坏时间复杂度.最好时间复杂度.平均时

基数排序与桶排序,计数排序【详解】

桶排序简单入门篇^-^ 在我们生活的这个世界中到处都是被排序过的东东.站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东东都需要排序,可以说排序是无处不在.现在我们举个具体的例子来介绍一下排序算法. 首先出场的是我们的主人公小哼,上面这个可爱的娃就是啦.期末考试完了老师要将同学们的分数按照从高到低排序.小哼的班上只有5个同学,这5个同学分别考了5分.3分.5分.2分和8分,哎,考得真是惨不忍睹(满分是10分).接下来将分

桶排序

假设现在有一组小于M的正整数 a1. a2 ,-- ,an ,对它们排序可以采用以下的思路:使用一个大小为M的数组buckets,这个数组的每一个单元称为一个个的bucket,桶,初始化全部为0.扫描数组a,当扫描到ai的时候,buckets[ai] 加1.这样当a扫描完之后,扫描buckets,打印非零单元的下标,它的值是几就打印几次.打印出来的值实际上就是排好序之后的数组a了.我们可以依次把它们赋值给a,使得a有序. 代码如下: #include<iostream> using names

基数排序(桶排序) 不同方法

详细解释:算法导论/数据结构书 1.链式基数排序 //n个数,每个数有g个关键字//排序:从最后的关键字开始到最前的关键字//分配+收集//每个关键字分配+收集需要n+n时间,而共有g个关键字,时间复杂度为O(2ng),效率很高.//如果用数组,数据集中在一个区间,则区间的长度很长,另外的区间的内存浪费了.//用链表可以解决这个问题,且数据不需要先后顺序,所以无必要非要用数组 1 #include <stdio.h> 2 #include <stdlib.h> 3 //个数 4 #

重复造轮子系列--桶排序

理解了基数排序,也就理解了桶排序. 桶排序就是基数排序的一种优化,从MSD开始,即取最高位来排一次序,如果最高位没有重复(意味着没有冲突需要处理),是算法的最佳状态,O(n). 如果有冲突,就将冲突的元素存放到对应的桶里(代码就是一个链表或者数组或者stl容器),然后对每个桶进行一次插入排序,平均情况的话冲突很小的,桶里的元素的数量就不多,速度很快, 如果冲突集中在几个桶甚至一个桶里,那么就出现了算法的最差情形,也就是O(n^2)的复杂度. 下面是例子代码实现: 1 template<typen

桶排序总结

数据结构排序算法之——桶排序(Bucket sort) 插入排序想关链接: 维基百科:https://zh.wikipedia.org/wiki/%E6%A1%B6%E6%8E%92%E5%BA%8F 极客学院想关介绍:http://wiki.jikexueyuan.com/project/easy-learn-algorithm/bucket-sort.html 桶排序主要用于有大量重复数据和明确知道数据边界的情况下,进行统计的排序 基本的算法思想是: 假设数据的边界的长度为arrayLen,