桶排序算法

桶排序的基本思想

桶排序利用函数的映射关系,将待排序的数组分成了N个块(桶)。实际上,桶排序的f(k)值的计算,其作用就相当于快排中划分,已经把大量数据分割成了基本有序的数据块(桶)。然后只需要对每个桶中的少量数据做比较排序(比较排序:即在比较的基础上进行交换,达到排序效果)即可。

假如待排序列K= {49、 38 、 35、 97 、 76、 73 、 27、 49 }。这些数据全部在1—100之间。因此我们定制10个桶,然后确定映射函数f(k)=(k*10)/(k.max)。则第一个关键字49将定位到第4个桶中(49*10/97=5)。依次将所有关键字全部堆入桶中,并在每个非空的桶中进行快速排序,如下图所示。

待排序的数组为:

那么接下来只要对这些子数组排序即可。

实用范围:

数组的数必须是正数,但我们可以通过对每个数加上一个值a,让它变为正数,排序完成后再减去a。

时间复杂度:

(1) 循环计算每个关键字的桶映射函数,这个时间复杂度是O(N)。

(2) 利用先进的比较排序算法对每个桶内的所有数据进行排序,其时间复杂度为:对于N个待排数据,M个桶,平均每个桶[N/M]个数据的桶排序平均时间复杂度为:O(N)+O(M*(N/M)*log(N/M)) = O(N+N*(logN-logM)) = O(N+N*logN-N*logM)。

提高算法在于:

(a) 映射函数f(k)能够将N个数据平均的分配到M个桶中,这样每个桶就有[N/M]个数据量。当N=M时,即极限情况下每个桶只有一个数据时。桶排序的最好效率能够达到O(N),最坏(所有元素在一个桶中)。

(b) 尽量的增大桶的数量。极限情况下每个桶只能得到一个数据,这样就完全避开了桶内数据的“比较”排序操作。当然,做到这一点很不容易,数据量巨大的情况下,f(k)函数会使得桶集合的数量巨大,空间浪费严重。这就是一个时间代价和空间代价的权衡问题了。

C++代码:

#include <iostream>
using namespace std;
namespace mySort
{
	float Max(float *array, int begin,int end)
	{//获取数组中最大的数
		float ret = -1;
		for (int i = begin; i <= end; ++i)
			ret = (ret < array[i]) ? array[i] : ret;
		return ret;
	}
	int getIndex(float a, float max)
	{//获取桶的索引位置。
		return (int) ((a * 10) / max);
	}
	void insertSort(float * array, int begin, int end)
	{
		for (int i = begin; i < end; ++i)
		{
			int j = i + 1 ;
			float tmp = array[j];
			for (; j > 0;j--)
			{
				if (tmp < array[j - 1])
					array[j] = array[j - 1];
				else
					break;
			}
			array[j] = tmp;
		}
	}
	void radixSorting(float array[], int begin, int end)
	{
		int arraySize = end - begin + 1;
		float max = Max(array, begin, end);
		const int countSize = 11; //(N * 10 / M && N < M ) 有 11 种可能
		int count[countSize];
		float * temp = new float[arraySize];
		memset((void*)count,0, sizeof(count)); //初始化为0

		for (int i = begin; i <= end; ++i) //记录每个桶中的元素个数
		{
			count[getIndex(array[i], max)] += 1;
		}
		for (int i = 0; i < countSize-1; ++i)
		{
			count[i + 1] += count[i];
		}
		for (int i = end; i >= begin; --i)
		{
			int j = getIndex(array[i], max);
			temp[count[j]-1] = array[i];
			--count[j];
		}
		for (int i = 0; i < countSize - 1 ; ++i)
		{
			if (count[i] < count[i + 1])
			{
				mySort::insertSort(temp, count[i], count[i + 1] - 1);
			}
		}
		memcpy((void*)array, (void*)temp, arraySize*sizeof(float));
		delete [] temp;

	}
};

int main()
{
	float a[] = { 49, 38 , 35, 97 , 76, 73 , 27, 49 };
	int length = sizeof(a) / sizeof(float);
//	mySort::insertSort(a, 0, length - 2);
	mySort::radixSorting(a, 0, length - 1);
	return 0;
}

总结:桶排序和计数排序有着惊人的相似之处。计数排序将每个元素投射于数组的每个空间,但有着:必须是整数,并且空间耗费大,与具体待排序的数有关。而桶排序则用更小的空间(O(N)且与具体待排序数无关),只记录了每个桶的索引,但需要对每个桶的数据进行排序,适用范围也更广泛。计数排序这种用空间换时间的方法和Hash有着很大的相似之处。

桶排序算法,布布扣,bubuko.com

时间: 2024-08-04 08:49:09

桶排序算法的相关文章

8-4.桶排序算法详解

1. 桶排序介绍 桶排序(Bucket sort)是一种基于计数的排序算法,工作的原理是将数据分到有限数量的桶子里,然后每个桶再分别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序).当要被排序的数据内的数值是均匀分配的时候,桶排序时间复杂度为Θ(n).桶排序不同于快速排序,并不是比较排序,不受到时间复杂度 O(nlogn) 下限的影响. 桶排序按下面4步进行: 1. 设置固定数量的空桶. 2. 把数据放到对应的桶中. 3. 对每个不为空的桶中数据进行排序. 4. 拼接从不为空

桶排序算法-python实现

来源: <啊哈算法> 5个数字 5 3 5 2 8需要排序. 用到了桶排序思路 l=[0,0,0,0,0,0,0,0,0,0] p=[5,3,5,2,8] for i in range(10):     for j in p:         if i==j:             l[i]+=1 print l new_l=[] for i in range(10): #核心点在这里     if l[i]!=0:         for j in range(l[i]):        

算法导论------------桶排序算法之研究

举个来说明桶排序的过程,假设现在有A={0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.68},桶排序如下所示: 研究过计数排序我们知道了----计数排序是假设输入是由一个小范围内的整数构成,而桶排序则假设输入由一个随机过程产生的,该过程将元素均匀而独立地分布在区间[0,1)上.当桶排序的输入符合均匀分布时,即可以线性期望时间运行.桶排序的思想是:把区间[0,1)划分成n个相同大小的子区间,成为桶(bucket),然后将n个输入数分布到各个桶中去,对

桶排序 - 算法 - PHP版

<?php //初始化数组,默认值为0; $arr = array(); for ($i = 0; $i <= 10; $i++) { $arr[$i] = 0; } //定义测试数据 $arr1 = array(5, 3, 5, 3, 7); //根据数据 对默认数组的对应元素进行+1 for ($j = 0; $j < count($arr1); $j++) { $arr[$arr1[$j]]++; } //循环输出 for ($k = 0; $k <= 10; $k++) {

最快最简单的排序算法:桶排序

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

三种线性排序算法(计数、基数、桶排序)的简单实现

一.计数排序 计数排序假设n个输入元素中的每一个都是介于0到k之间的整数.此处k为某个整数(输入数据在一个小范围内). 基本思想: 计数排序的基本思想是对每一个输入元素x,确定出小于x的元素的个数.然后再将x直接放置在它在最终输出数组中的位置上. 如下图所示: 由于数组中可能有相等的数,在处理时需要注意. 时间复杂度和空间复杂度分析 算法总时间Θ(k + n).当k=O(n)时,计数排序的运行时间是Θ(n). 空间复杂度是O(n+k).需要两个辅助数组:存放排序结果的数组B[n],存放临时结果的

啊哈!算法之快速排序与桶排序

啊哈!算法之快速排序与桶排序 1.快速排序算法 快速排序由 C. A. R. Hoare(东尼·霍尔,Charles Antony Richard Hoare)在1960 年提出,之后又有许多人做了进一步的优化.在数列种随机找出一个基准数,因为数列是杂乱的,所以取首项为基准数.从后往前找到比基准数大的位置,再从前往后找到比基准数小的位置,交换元素:右游标向前移动与左游标向后移动,它们相遇时用基准数的位置与相遇的位置交换.此时原来数列以相遇的位置被划分为了两个需要排序的数列,再次执行上述过程:当左

排序算法&lt;No.2&gt;【桶排序】

算法,是永恒的技能,今天继续算法篇,将研究桶排序. 算法思想: 桶排序,其思想非常简单易懂,就是是将一个数据表分割成许多小数据集,每个数据集对应于一个新的集合(也就是所谓的桶bucket),然后每个bucket各自排序,或用不同的排序算法,或者递归的使用bucket sort算法,往往采用快速排序.是一个典型的divide-and-conquer分而治之的策略. 其中核心思想在于如何将原始待排序的数据划分到不同的桶中,也就是数据映射过程f(x)的定义,这个f(x)关乎桶数据的平衡性(各个桶内的数

【啊哈!算法】最快最简单的排序——桶排序

转自:http://bbs.ahalei.com/thread-4399-1-1.html 最快最简单的排序——桶排序 在我们生活的这个世界中到处都是被排序过的.站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东西都需要排序,可以说排序是无处不在.现在我们举个具体的例子来介绍一下排序算法. 首先出场的我们的主人公小哼,上面这个可爱的娃就是啦.期末考试完了老师要将同学们的分数按照从高到低排序.小哼的班上只有5个同学,这5个