深度理解排序算法——计数排序

之前的博文所讲解的堆排序、希尔排序、归并排序、快速排序,它们都属于比较排序,而在排序算法也有一部分排序不是通过比较来的得出结果的,就好比如今天所要讲的计数排序。

计数排序:

所谓计数排序,就是将统计所有元素出现的次数,再根据次数将对应数据一一更新的数组中
图解:
深度理解排序算法——计数排序_第1张图片
但是我们我们要怎么存放数据出现的次数的数组与被排序数组中的元素一一对应呢,这里需要借助映射的原理
在打印数据的时候,只需要将存放数据次数的数组下标加上被排数组最小值就是需要打印的数据
在这里插入图片描述
深度理解排序算法——计数排序_第2张图片
//代码实现

void CountSort(int* a, int n)
{
	int min = a[0], max = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] < min)
		{
			min = a[i];
		}

		if (a[i] > max)
		{
			max = a[i];
		}
	}

	int range = max - min + 1;
	int* countA = (int*)malloc(sizeof(int) * range);
	memset(countA, 0, sizeof(int) * range);

	// 统计次数
	for (int i = 0; i < n; i++)
	{
		countA[a[i] - min]++;
	}

	// 排序
	int k = 0;
	for (int j = 0; j < range; j++)
	{
		while (countA[j]--)
		{
			a[k++] = j + min;
		}
	}
}

优缺点分析:

1、对被排序的数据大小要求苛刻,只有在数据较为集中的情况下(方差很小)时间才会快,并且空间利用率高,否则会造成大量的空间浪费
2、只能针对整型数据的排序,例如浮点型、字符型的数据计数排序无法实现

时间复杂度:

显然是O(N+Range)
具体是多少取决于Range的大小,
可以发现当Range很小的时候计数排序的时间复杂度是O(N)可以说是非常非常快的,超过了之前讲的所有排序算法
但是一旦Range大小非常大,比如在一个数组大小为2的数组,一个数是0,另一个数是M(非常非常大的一个数),那么Range也将变得非常非常大,运行速度就会变得非常之慢。

你可能感兴趣的:(排序算法,算法,数据结构)