计数排序的实现

计数排序是非比较排序的一种,是对哈希直接定址法的变形应用,其操作步骤如下:

1.统计相同元素出现的次数。

2.根据统计结果将序列回收到原来的序列中。

拿一组重复元素较多的数组来举例子: 10    11     10     15    14     15    11     10    13     11

1.统计相同元素出现的个数

要想事统计的元素尽量的少,就应该把整个数组的最小元素和最大元素求出来,求两者的差+1

(range),再进行动态内存开辟,开辟的空间大小为sizeof(int)*range,然后遍历一遍原数组,将

每个元素的大小减去最小值,作为开辟的新数组的下标,下标对应的元素++,从而达到了统计相

同元素出现的个数的目的。

如下图:

计数排序的实现_第1张图片

这就达到了统计相同元素出现的个数的效果,一定要先求最大元素和最小元素,不让动态开辟的空

间可能会过大到最后内存泄漏。

2.根据统计结果将序列回收到原来的序列中。

需要用两个循环进行实现,一个循环用来遍历count数组的下标,另一个循环用来--count数组中的

元素,将其存到a数组中,切记要将count中的元素还原回来(+min),让后再存入a数组中。

如下图:

计数排序的实现_第2张图片

这个图把每个细节都体现的淋漓精致,所以这就是计数排序的实现,计数排序适用于一些有较多

重复元素的数组排列,会非常快,相较于之前提到的其他排序,这个排序比较特殊,他是一个非比

较排序,代码如下:

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

		if (a[i] < min)
		{
			min = a[i];
		}
	}
	int range = max - min + 1;
	//计数
	int* count = (int*)malloc( sizeof(int) * range);
	if (count == NULL)
	{
		perror("malloc fail");
		return;
	}
	memset(count, 0, sizeof(int) * range);
	for (int i = 0; i < n; i++)
	{
		count[a[i] - min]++;
	}
	//排序
	int j = 0;
	for (int i = 0; i < range; i++)
	{
		while (count[i]--)
		{
			a[j++] = i + min;
		}
	}
	free(count);
}

从代码中可以看出,除了找最大和最小元素的时候存在比较(这不在计数排序的范畴里,为了节省

空间加的一段代码),其他地方都没有用到比较操作符,所以这就是非比较排序,计数排序。 

 

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