算法--桶排序

本文介绍了桶排序的基本思想及其在均匀分布数据上的高效表现。通过将数据映射到多个桶中,并采用高效的排序方法对各桶内数据进行排序,桶排序能够在特定条件下达到线性时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

桶排序

当桶排序的输入符合均匀分布时,可以以线性期望时间运行。桶排序是对输入做了假设。

思想:将区间划分为几个相同大小的子区间。将n个元素分布到桶中也就是区间中。这种分布是使用一个函数进行映射。此时就已经对数据进行了分区,其实就是有点类似快速排序一样,不过分区间的方式不同而已。然后再对区间中的数据进行排序,这个时候我们可以使用效率较高的排序方法进行排序。我们可以使用链表来操作。

效能分析:将元素映射到桶中使用的时间是O(n)。利用先进的比较排序算法对每个桶内的所有数据进行排序,其时间复杂度为  O(N*logN),所以对于N个待排数据,M个桶,平均每个桶[N/M]个数据的桶排序平均时间复杂度为:

 O(N)+O(M*(N/M)*log(N/M))=O(N+N*(logN-logM))=O(N+N*logN-N*logM))  N=M时,即极限情况下每个桶只有一个数据时。桶排序的最好效率能够达到O(N)。 

即使输入不符合均匀分布,桶排序也仍然可以以线性时间运行。只要输入满足同的尺寸的平方和与总的元素数目呈线性关系。桶数量M越大,其

效率越高,最好的时间复杂度达到O(N)。 当然桶排序的空间复杂度 为O(N+M) 


template<class T>
class BucketNode
{
public:
	T key;
	BucketNode<T>* next;
	BucketNode()
	{
		next=NULL;
	}
};

template<class T>
class BucketList
{
public:
	BucketNode<T>** root;//指向桶元素中最顶端那个元素。因为这个指针数组中每一个元素也是一个BucketNode*类型
	BucketList()
	{
		root=NULL;
	}
	void BUCKET_SORT(T* bucketArray,int length);//桶排序
	
};

void Test();

#include "stdafx.h"
#include "BucketSort.h"
template<class T>
void BucketList<T>::BUCKET_SORT(T* bucketArray,int length)
{
	//现在假设是在0-100的元素
	root=new BucketNode<T>*[length];
	for (int i=0;i<length;i++)
	{
		*(root+i)=new BucketNode<T>();//有一个头元素,也就是说在这个元素中什么都不存放,有点浪费?
	}
	//一个思想是不想一下子就建立这么多的索引,有的空间也是在浪费。不行,如果按照需求建立的话,后面的元素怎样的查找
	//找到这个索引所在的位置呢,必须是实现就分配好了的
	int index=0;
	BucketNode<T>*tempNode=NULL;
	for (int i=0;i<length;i++)
	{
		index=*(bucketArray+i)/10;//因为实在0-100之间的元素。索引值为其十位的值
		tempNode=*(root+index);//得到索引的这个元素
		BucketNode<T>*newNode=new BucketNode<T>();
		newNode->key=*(bucketArray+i);
		if (tempNode->next==NULL)//若元素为空
		{
			tempNode->next=newNode;
		}
		else
		{
			while(tempNode->next!=NULL&&tempNode->next->key<newNode->key)
			{
				tempNode=tempNode->next;
			}
			newNode->next=tempNode->next;
			tempNode->next=newNode;
		}
	}
	for (int i=0;i<length;i++)
	{
		tempNode=*(root+i);
		while(tempNode->next!=NULL)
		{
			cout<<tempNode->next->key<<" ";
			tempNode=tempNode->next;
		}
		cout<<endl;
	}
}

void Test()
{
	int testArray[]={16,4,10,14,7,9,3,2,8,1};
	cout<<"排序前的数组"<<endl;
	for (int i=0;i<10;i++)
	{
		cout<<testArray[i]<<" ";
	}

	BucketList<int>*bucketList=new BucketList<int>();
	cout<<"排序之后的数组"<<endl;
	bucketList->BUCKET_SORT(testArray,10);
}

当然我上面桶内部的插入排序并不是高效的排序方式。可以使用快排序,这个时候我们的结点势必要有prev的指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值