数据结构和算法 ——计数排序

计数排序

根据我自己所学到的以及所认识的,对计数排序做一个总结化的讲解。

目录
一、了解计数排序
二、计数排序的工作原理
三、计数排序的弊端以及优化
四、代码演示


一、了解计数排序

计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。这一排序算法是利用一个额外的数组来对当前一组数据进行排序的算法,它和其他排序算法不同,不需要重复遍历,只需对数据遍历一遍,将一组数据中相同的元素记录在一块,然后再对其进行特殊的输出即可。






二、计数排序的工作原理

下面我们准备一组无序的整型数据做讲解:
数据结构和算法 ——计数排序_第1张图片
解析: 准备一个大于无序数组(arr)中所存储的最大值的临时数组(tempArr),然后遍历arr,将当前数组元素作为tempArr下标,让临时数组中相对应的下标所对应的值递增,核心代码为tempArr[arr[i]]++(本质上是用下标做一系列操作),直到遍历完成,tempArr中的下标就是arr的元素,tempArr中的元素就是当前下标所存在的个数。其实我们后面输出的主要是index,相对应得元素值只是作为记录index所要出现的次数。






三、计数排序的弊端以及优化

对于弊端,显而易见,是一种牺牲空间换取时间的一种算法,那么现在就出现了一个问题,如果现在arr中的值最大值为108甚至更多,那么tempArr所需要开辟的空间所换取的时间显然是亏到姥姥家了,我还不如用冒泡排序呢。但是我们也能用其他的方式来代替数组,这里使用C++中STL的map来代替数组,使用key值保存arr中的元素,value值保存key值出现的次数,完美模仿了上面的功能且优化了开辟无用空间过多的情况。当然,若你的key值是自定义数据类型,那么只需要在原有的思想上稍加改进即可。






四、代码演示

上面已经把思路给想好了,接下来就是使用代码来实现,代码如下:

void countNumberSort()
{
	int arr[] = { 5,8,2,4,6,3,8,1,5,4,5,6,7,2 };
	int len = sizeof(arr) / sizeof(arr[0]);
	cout << len << endl;
	mapm;
	
	for (int i = 0; i < len; i++)
	{

		m[arr[i]]++;
	}

	for (map::iterator it = m.begin(); it != m.end();)
	{
		if (it->second--)
		{
			cout << it->first << " ";
		}
		else
		{
			it++;
		}
	}
}




注意:当出现其他题目,例如要你统计字符数量且对其排序,这类题目也可以使用计数排序进行解答,需要灵活的使用下标,甚至是自定义数据类型,我们只需要重载相对应的运算符,即可在map上运行且排序方式更加灵活。

最后:学习编程两年不到半的小菜鸡对计数排序的学习总结,若有不足请指正,感谢大佬们的阅读!

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