《算法导论》——桶排序

《算法导论》——桶排序

  1. 桶排序的思想就是把区间[0, 1)划分成n个相同大小的子区间,每一个区间称为桶(bucket)。然后,将n个输入数据分布到各个桶中去。因为输入数均匀且独立均匀分布在[0, 1)上,所以一般不会有很多数落在一个桶中的情况。为得到结果,先对各个桶中的数进行排序,然后按次序把各个桶中的元素列出来即可。时间复杂度O(n).
  2. 在桶排序算法中,假设输入的是一个含n个元素的数组A,且每个元素满足0≤A[i]<1。另外,还需要一个辅助数组B[0…n-1]来存放链表(桶),并假设可以用某种机制来维护这些表

伪代码
伪代码

c++代码

#include  "iostream"
#include "stdlib.h"
using namespace std;

struct Node
{
	double value;
	struct Node *next;
};

void BUCKET_SORT(double* array, int len)
{
	int count = 0;
	Node *bucket = new Node [len] ;     //开辟了一块连续的存储len个Node(头节点)的数组
	for (int i = 0; i < len; i++)		//初始化头
	{
		bucket[i].value = 0;
		bucket[i].next = NULL;
	}
	for (int j = 0; j < len; j++)
	{
		Node *insert = new Node;
		insert->value = array[j];
		insert->next = NULL;
		int temp = array[j] * 10;
		if (bucket[temp].next == NULL) //链表中只有头节点
		{
			bucket[temp].next = insert; //直接插入后
		}
		else                             //有多个节点,排序插入
		{
			Node *q = &bucket[temp];    //头节点
			Node *p = bucket[temp].next;
			while (p!= NULL &&( p->value <= array[j]))
			{
				p = p->next;
				q = q->next;
			}
			q->next = insert;
			insert->next = p;
		}
	}
	for (int k = 0; k < len; k++)
	{
		Node *p = bucket[k].next;
		while (p != NULL)
		{
			array[count++] = p->value;
			p = p->next;
		}
	}

}
void main()
{
	double a[] = { 0.12, 0.13, 0.45, 0.53, 0.65, 0.48, 0.34, 0.45 };
	int length = sizeof(a) / sizeof(a[0]);
	BUCKET_SORT(a, length);
	for (int i = 0; i < length; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
	system("pause");
}

桶排序也可以拓展至整数部分。


转载
3. 桶排序在海量数据中的应用

一年的全国高考考生人数为500 万,分数使用标准分,最低100 ,最高900 ,没有小数,你把这500 万元素的数组排个序。

分析:对500W数据排序,如果基于比较的先进排序,平均比较次数为O(5000000*log5000000)≈1.112亿。但是我们发现,这些数据都有特殊的条件: 100=<score<=900。那么我们就可以考虑桶排序这样一个“投机取巧”的办法、让其在毫秒级别就完成500万排序。

方法:创建801(900-100)个桶。将每个考生的分数丢进f(score)=score-100的桶中。这个过程从头到尾遍历一遍数据只需要500W次。然后根据桶号大小依次将桶中数值输出,即可以得到一个有序的序列。而且可以很容易的得到100分有**人,501分有*人。

实际上,桶排序对数据的条件有特殊要求,如果上面的分数不是从100-900,而是从0-2亿,那么分配2亿个桶显然是不可能的。所以桶排序有其局限性,适合元素值集合并不大的情况。

猜你喜欢

转载自blog.csdn.net/weixin_42809993/article/details/84571045