262-基数排序(桶排序)算法的思想和性能分析

262-基数排序(桶排序)算法的思想和性能分析,第1张

基数排序算法的思想和性能分析

基数排序算法的思想

基数排序也称作: 桶排序

思想: 把所有元素的个位进行排序,然后十位进行排序,然后百位进行排序,依次向高位递进,最后得到一个全局的小到大或者大到小的序列。

我们看下面序列:

如果每次比较的都是1位的话,比如说57和54,先比较个位,7大于4,十位,是5==5,也就是说,每次比较的这一位的话,取值范围就是0-9


我们现在对下面这个序列进行桶排序:

从左向右,依次遍历原始的数据,最开始,是个位进行比较
43的个位是3,我们把43放在3号桶,47的个位是7,我们把47放在7号桶
11的个位是1,我们把11放在1号桶
以此类推。

我们先利用所有元素的个位和桶的序号进行比较,相等的话就放进去。

然后依次遍历0-9号桶,把所有的元素拷贝到原始的序列中。

从全局来说,数列并没有变成有序的,但是我们看到它们的个位变得有序了。

因为最长的数字是2位。所以我们要计算到十位。

接下来,我们从头开始遍历,根据每个元素的十位的数字,放到与之相等的桶号的桶中。

然后从0号-9号桶,依次把元素拷贝到原始的序列中。

处理完了个位和十位之后,现在的序列就是有序的了!

基数排序的核心代码:(循环每次取出一个位上的数字)

len表示序列中的最多位数。
index依次输出number的个位,到十位,到百位,一直到最高位的值。

桶:

  • 有的桶的元素多,有的桶的元素少,vector可动态扩容。

基数排序算法的代码实现

如果我们用基数排序排序原始的乱序,对于整数和浮点数的排序方式在代码上是有区别的,没有办法得到统一。
我们在实现的时候,要考虑到负数的情况:

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

//基数排序代码
//时间复杂度:O(nd)  空间复杂度:O(n)  稳定性:稳定的排序
void RadixSort(int arr[], int size)
{
	int maxData = arr[0];
	for (int i = 1; i < size; i++)//找序列中的最大值 
	{
		if (maxData < abs(arr[i]))//abs是求绝对值 
		{
			maxData = abs(arr[i]);
		}
	}

	int len = to_string(maxData).size();
	//转成C++string字符串,然后调用size函数,获取字符个数 

	vector<vector<int>> vecs;//定义桶 
	int mod = 10;
	int dev = 1;

	for (int i = 0; i < len; mod *= 10, dev *= 10, i++)//O(d) d:数据的长度
	{
		vecs.resize(20);//20个桶,为了能处理负数 -9 - 9

		for (int j = 0; j < size; j++) // O(n)
		{
			//得到当前元素第i个位置的数字
			int index = arr[j] % mod / dev + 10;//前面10个桶存储负数,后面10个桶存储正数
			vecs[index].push_back(arr[j]);
		}

		//依次遍历所有的桶,把元素拷贝回原始的数组当中
		int idx = 0;
		for (auto vec : vecs)//O(20) //从0-19号桶依次拷贝元素到原始数组中 
		{
			for (int v : vec)//O(n)    O(20)*O(n) = O(n)
			{
				arr[idx++] = v;
			}
		}

		vecs.clear();//清空桶 
	}
}

int main()
{
	int arr[10];
	srand(time(NULL));

	for (int i = 0; i < 10; i++)
	{
		arr[i] = rand() % 100 + 1;
	}

	arr[9] = -123;
	arr[6] = -38;

	for (int v : arr)
	{
		cout << v << " ";
	}
	cout << endl;

	RadixSort(arr, 10);

	for (int v : arr)
	{
		cout << v << " ";
	}
	cout << endl;
}

基数排序算法的性能分析 时间复杂度和空间复杂度

时间复杂度: O(nd),d为数据的长度

空间复杂度: O(n)

开辟的桶的大小,存放的是所有的元素,所以空间复杂度是O(n)

稳定性

稳定性: 是稳定的排序

如果元素相同,都是在一个桶里放着,而且都是 从左到右遍历,从左向右放进桶的;

而且最后桶里的元素也是按左右顺序依次拷贝到原序列中。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/langs/1295474.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-10
下一篇2022-06-10

发表评论

登录后才能评论

评论列表(0条)

    保存