排序简解——非比较排序类

计数排序

计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。 [1-2]  当然这是一种牺牲空间换取时间的做法,而且当O(k)>O(n*log(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(n*log(n)), 如归并排序,堆排序)

代码如下(从后往前填充,不需要计算元素位置,相同元素一定是从后向前填充):

#include<iostream>
using namespace std;
const int max = 100;//0-99
void countSort(int a[], int size)
{
	int counter[max],i,temp;
	int aEnd = size-1;
	memset(counter, 0, max*sizeof(int));
	for (i = 0; i < size; i++)
		counter[a[i]]++;
	for (i = max - 1; i >= 0; i--)
	{
		while (counter[i] != 0)
		{
			counter[i]--;
			a[aEnd--] = i;//倒序保证排序稳定性,计数器类似于栈的先进后出的思想,利用倒序放置将相同元素恢复原始顺序
		}
	}	
}
int main()
{
	int size;
	while (cin >> size)
	{
		int A[100];
		for (int i = 0; i < size; i++)
			cin >> A[i];
		countSort(A, size);
		for (int i = 0; i < size; i++)
			cout << A[i]<<' ';
		cout << endl;
	}
	system("pause");
	return 0;
}

计数排序优化

优化思想来源:https://blog.csdn.net/double_happiness/article/details/72424452

类似于直接哈希算法,当数组中的元素不是从最小的数开始的,而是像(1000,1002,1003,1004,1000)这样的数组采用计数排序时,如果我们依旧是开辟最大数+1的空间时,就会使前面的空间全部浪费,因此应该找出最大值和最小值,两者相减就会得到对应的临时数组空间的大小,然后对其进行相应的映射,得到排好序的有序序列。

猜你喜欢

转载自blog.csdn.net/zhang_postgradu/article/details/82956555