计数排序——O(n)复杂度基于非比较的排序方法

本文详细介绍了一种非基于比较的排序算法——计数排序。计数排序由Harold H. Seward于1954年提出,适用于整数排序,其时间复杂度为O(n+k),优于比较排序算法。文章解释了计数排序的基本思想、步骤,并提供了参考代码。
摘要由CSDN通过智能技术生成

基本思想

计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。

计数排序的基本思想是:对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有7个元素的值小于x的值,则x可以直接存放在输出序列的第8个位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。

计数排序步骤

  1. 找出待排序的数组中最大和最小的元素
  2. 统计数组中每个值为i的元素出现的次数,存入数组C的第i项
  3. 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
  4. 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
有三个参数:
  • 输入数组sourceArr[], 长度为sourceArr.size(),
  • 需要一个数组存放结果resultArr,长度大小跟sourceArr相同。
  • 另外需要一个辅助数组,tempArr,长度大小为sourceArr中最大的元素值。

参考代码

#include "iostream"
#include "vector"
using namespace std;

class countSort{

public:
	static void CSort(vector<int> sourceArr, vector<int> resultArr, const int maxNum)
	{
		vector<int> tempArr(maxNum+1);//注意分配给临时数组的大小为maxNum+1,因为后面要访问到tempArr[maxNum]
		for (int i = 0; i < tempArr.size(); i++)
			tempArr[i] = 0;
		for (int i = 0; i < sourceArr.size(); i++)
		{
			tempArr[sourceArr[i]]++;
		}
		//注意<=是小于等于maxNum,不要漏掉最后一个元素,开始从i=1
		for (int i = 1; i <= maxNum; i++)
			tempArr[i] += tempArr[i - 1];
		//注意tempArr[sourceArr[i]] - 1 代表的是sourceArr[i]在结果数组中的位置
		//在放好之后要减一 因为有重复值相等的数
		for (int i = sourceArr.size() - 1; i >= 0; i--)
		{
			resultArr[tempArr[sourceArr[i]] - 1] = sourceArr[i];
			tempArr[sourceArr[i]]--;
		}
		//输出查看结果
		for (int i = 0; i < resultArr.size(); i++)
			cout << resultArr[i] << " ";
		cout << endl;
	}

	int getMaxNum(vector<int> arr)
	{
		int max = 0;
		for (int i = 0; i < arr.size(); i++)
		{
			if (arr[i] > max)
				max = arr[i];
		}
		return max;
	}
};

int main()
{
	vector<int> arr = { 0, 2, 12, 3, 0, 2, 3, 0, 3,5,5,2,3,7,8,4};
	vector<int> ans(arr.size());
	countSort csort;
	int max = csort.getMaxNum(arr);
	csort.CSort(arr, ans, max);
	return 0;
}

时间复杂度:O(n+maxNum)
空间复杂度:O(n+maxNum)

注意:计数排序是稳定的排序方法。

1. 计数排序是有效的,如果输入数据的范围是不显著大于数字的个数。

2. 它不是一个基于比较的排序。它运行的时间复杂度为O(n)

3. 它经常被用来作为另一个排序算法像基数排序的一个子程序。

4. 计数排序可以扩展到负输入也可以。




参考资料:
http://baike.baidu.com/view/1209480.htm?wtp=tt



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值