C++实现基数排序(radix sort)

在weiss的书中,推导了基于比较的排序算法的一般下界为Nlog(N)。但是一些排序不基于比较的可以达到线性时间,称为线性时间排序(Linear-Time Sort),比如桶排序(Bucket Sort)和基数排序(Radix Sort)。桶排序比较简单,基数排序相当于通过循环进行了多次桶排序。基数排序的原理可以参考这篇博客。它在数据量有限制(比如知道最大的数是多少,知道总共最多有多少种元素个数)的时候,可以通过这些信息量,获得更快的排序时间(但有时候,当待排系列的每个元素组成部分很长时,并不一定比基于比较的排序算法快)。基数排序常见的应用是排序整数,字符串等。这里简化问题,待排序列中只有三位数的正整数存在。记录一下基数排序的基本实现。

#include  
#include  
#include  
#include  
#include  
#include  
#include
using namespace std;

/*
 基数排序
 简化了问题,待排向量为整型,且为三位数
*/
void radixSort(vector & source)
{
	const int BUCKETS = 10;
	vector> buckets(BUCKETS);

	//外层循环是根据数字的位数确定的。因为是三位数,所以从2到0
	for (int pos = 0; pos <= 2; ++pos)
	{
		//pos = 0, 表示个位数
		//pos = 1, 表示十位数
		//pos = 2, 表示百位数
		int denominator = static_cast(pow(10, pos)); // 取某一位数的时候需要用的分母
		for (int & tmp : source) // 按数字放入桶中
			buckets[(tmp / denominator) % 10].push_back(tmp);

		int index = 0; 
		// 从桶中取出来,放入原来的source序列中,以备下次遍历时使用
		for (auto & theBucket : buckets) 
		{
			for (int & k : theBucket)
				source[index++] = k;

			theBucket.clear();//一定要清空桶中数据
		}
	}
}

/*输出向量*/
template
void printVector(vector & v)
{
	copy(v.cbegin(), v.cend(), ostream_iterator(cout, " "));
	cout << endl;
}

int main()
{
	vector source;
	uniform_int_distribution u(100, 999);
	default_random_engine e(static_cast(time(0)));
	for (int i = 0; i < 15; i++)
	{
		source.push_back(u(e));
	}

	cout << "排序前:" << endl;
	printVector(source);

	radixSort(source);

	cout << "排序后:" << endl;
	printVector(source);

	return 0;
}


运行结果如下:

C++实现基数排序(radix sort)_第1张图片




你可能感兴趣的:(算法)