算法导论 第八章 线性时间排序

第八章 线性时间排序

本章介绍了3种在线性时间内进行排序的算法,然而这几种算法存在诸多限制

1.计数排序

   计数排序算法基于以下假设:输入的每一个元素都是介于0到k之间;k的值是n的线性函数;空间效率低下;

template <class T>
void CountSort(T* a,int n,int k)
{
	int* c = new int[k + 1];
	T* b = new T[n];
	for (int i = 0; i <= k; ++i)
	{
		c[i] = 0;
	}
	for (int i = 0; i < n; ++i)
	{
		c[a[i]]++;
	}
	for (int i = 1; i <= k; ++i)
	{
		c[i] += c[i - 1];
	}
	for (int i = n - 1; i >= 0; --i)
	{
		b[c[a[i]] - 1] = a[i];
		c[a[i]]--;
	}
	for (int i = 0; i < n; ++i)
	{
		a[i] = b[i];
	}
	if (b != NULL)
	{
		delete [] b;
		b = NULL;
	}
	if (c)
	{
		delete [] c;
		c = NULL;
	}
}


2.基数排序算法

基数排序算法在输入元素在0到n^d次方时,拥有Θ(d*n)的时间复杂性,然而其并非本地排序,空间效率低下,而且常系数很大。

void RadixSort(int* a,int n,int k)
{
	
	int *c = new int[k];
	int *b = new int[n];
	int divisor = 1;
	int _max = a[0];
	for (int i = 1; i < n;++i)
	{
		if (_max < a[i])
		{
			_max = a[i];
		}
	}
	int d = (float)log((float)_max)/log((float)k) + 1;
	
	for (int j = 0; j < d; ++j)
	{
		for (int i = 0; i < k; ++i)
		{
			c[i] = 0;
		}
		for (int i = 0; i < n; ++i)
		{
			c[(a[i]/divisor)%k]++;
		}
		for (int i = 1; i < k; ++i)
		{
			c[i] += c[i - 1];
		}
		for (int i = n - 1; i >= 0; --i)
		{
			b[c[(a[i]/divisor)%k] - 1] = a[i];
			c[(a[i]/divisor)%k]--;
		}
		for (int i = 0; i < n; ++i)
		{
			a[i] = b[i];
		}
		divisor *=k;
	}
	if (c != NULL)
	{
		delete [] c;
		c = NULL;
	}
	if (b != NULL)
	{
		delete [] b;
		b = NULL;
	}
}


3.桶排序

桶排序的平均时间复杂性可以达到线性,然而其最坏运行时间依赖于对桶中数据的排序算法;同时空间效率也很低。

void BucketSort(int *a,int n)
{
	vector<list<int> > b(n);
	int _min,_max;
	_min = _max = a[0];
	for (int i = 1; i < n; ++i)
	{
		if (a[i] > _max)
		{
			_max = a[i];
		}else if(a[i] < _min)
		{
			_min = a[i];
		}
	}
	for (int i = 0; i < n; ++i)
	{
		b[(int)((a[i] - _min)*(n-1)/(_max - _min))].push_back(a[i]);
	}
	int j = 0;
	for (int i = 0; i < n; ++i)
	{
		if (b[i].size() > 0)
		{
			b[i].sort();
			while(!b[i].empty())
			{
				a[j] = b[i].front();
				j++;
				b[i].pop_front();
			}
		}
		
	}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值