【数据结构】中的计数排序(CountSort)

  • Post author:
  • Post category:其他



计数排序的概念:



1.计数排序的原理:设被排序的数组为A,排序后存储到B,C为临时数组。所谓计数,首先是通过一个数组C[i]计算大小等于i的元素个数,此过程只需要一次循环遍历就可以;在此基础上,计算小于或者等于i的元素个数,也是一重循环就完成。下一步是关键:逆序循环,从length[A]到1,将A[i]放到B中第C[A[i]]个位置上。原理是:C[A[i]]表示小于等于a[i]的元素个数,正好是A[i]排序后应该在的位置。而且从length[A]到1逆序循环,可以保证相同元素间的相对顺序不变,这也是计数排序稳定性的体现。在数组A有附件属性的时候,稳定性是非常重要的。




2.计数排序的前提及适用范围:A中的元素不能大于k,而且元素要作为数组的下标,所以元素应该为非负整数。而且如果A中有很大的元素,不能够分配足够大的空间。所以计数排序有很大局限性,其主要适用于元素个数多,但是普遍不太大而且总小于k的情况,这种情况下使用计数排序可以获得很高的效率。


计数排序算法的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有17个元素的值小于x的值,则x可以直接存放在输出序列的第18个位置上。


如下图所示:




实现计数排序的代码:






#include<iostream>
using namespace std;
#include<assert.h>
#pragma once

void CountSort(int *a, size_t n)
{
	assert(a);
	int max = a[0];
	int min = a[0];
	for (size_t 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 *Counts = new int[range];
	memset(Counts, 0, sizeof(size_t)*range);

	for (size_t i = 0; i < n; ++i)
	{
		Counts[a[i] - min]++;
	}
	size_t j = 0;

	for (size_t i = 0; i < n; ++i)
	{
		while (Counts[i]--)
		{
			a[j++] = i + min;
		}
	}
	delete[] Counts;
}
void printArray(int *a, size_t n)
{
	for (size_t i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
}
int main()
{
	int arr[] = { 1, 3, 5, 7, 0, 2, 9, 4, 6, 2 };
	//int arr[] = { 4, 38, 65, 97, 76, 13, 27, 49 };
	int n = sizeof(arr) / sizeof(arr[0]);
	cout << "进行计数排序前:";
	printArray(arr, n);
	CountSort(arr, n);
	cout << "进行计数排序后:";
	printArray(arr, n);
	system("pause");
	return 0;
}


运行的结果:






版权声明:本文为LX18792732127原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。