排序算法 —— 计数排序

目录

1.计数排序的思想

2.计数排序的实现

3.计数排序的分析

时间复杂度

空间复杂度

稳定性

优点

缺点


1.计数排序的思想

顾名思义,计数排序就是通过计数的方式来排序,其基本思想为:

  • 开辟一个计数数组,统计每个数出现的次数。
  • 遍历计数数组,将计数数组中的值依次填入待排序序列中,覆盖原来的值之后,排序便完成了。

2.计数排序的实现

计数排序最核心的两步就是统计数据出现的次数根据数据出现的次数排序

但是统计数据出现的次数时,我们需要开辟新的数组空间,并且将待排序的元素直接映射计数数组的下标,让对应的位置++,表示统计出了数据出现的次数;这样计数有个缺陷就是,当待排序的序列中的元素取值的最小值不是0时,比如:100、156、195、 163 、 101 、 200。此时我们应该开辟多大的空间呢?应该如何计数呢?

如果我们直接开辟201个空间,也让元素的值作为数组下标,这样直接计数会有空间的浪费,所以,我们可以统计出最小元素和最大元素,最小元素和最大元素的差值就是要开辟的空间的大小,然后我们可以采用间接映射的方式,将待排序元素的数值映射到计数数组对应的位置上。如下图所示:

代码如下:

复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void CountSort(int* a, int n)
{
	// 统计出最小元素和最大元素 
	int min = a[0], max = a[0];
	int i = 0;
	for (i = 0; i < n; i++)
	{
		if (a[i] < min)
			min = a[i];

		if (a[i] > max)
			max = a[i];
	}
	
	// 计算出取值范围 
	int range = max - min + 1;
	int* count = (int*)malloc(sizeof(int) * range);
	if (count == NULL)
	{
		perror("malloc fail");
		return;
	}
	// 将开辟的空间全部初始化为0 
	memset(count, 0, sizeof(int) * range);

	// 统计数据出现次数
	for (i = 0; i < n; i++)
	{
		count[a[i] - min]++;
	}

	// 排序
	int j = 0;
	for (i = 0; i < range; i++)
	{
		while (count[i]--)
		{
			a[j++] = i + min;
		}
	}
}

int main()
{
	int nums[] = {4,5,8,7,9,6,2,1,3,0};
	
	CountSort(nums,10);
	
	int i = 0;
	while(i < sizeof(nums) / sizeof(int))
	{
		printf("%d ",nums[i]);	
		i++;
	}
	
	return 0;
}

3.计数排序的分析

时间复杂度

分析计数排序的代码可知,计数排序需要遍历待排序序列两次,一次是统计最小值和最大值,一次是统计数据出现的此时,这里的时间复杂度就是O(N)了;

正式排序的时候,需要在范围内排序,假设范围是range,时间复杂度就是O(range)。

  • 综上所述,计数排序的时间复杂度为O(N+range)

空间复杂度

  • 使用计数排序的时候,我们额外开辟了range个空间,所以空间复杂度是O(range)

稳定性

  • 计数排序不考虑稳定性,因为,相同的数都揉到一团去了,说不清稳不稳定了。

优点

  • 计数排序在数据相对集中 的情况下效率很高

缺点

  • 计数排序需要映射下标,因此,计数排序只适用于整形数据
相关推荐
Gauss松鼠会2 小时前
【GaussDB】GaussDB锁阻塞源头查询
java·开发语言·前端·数据库·算法·gaussdb·经验总结
oier_Asad.Chen2 小时前
【洛谷题解/AcWing题解】洛谷P4011 孤岛营救问题/AcWing1131拯救大兵瑞恩
数据结构·笔记·学习·算法·动态规划·图论·宽度优先
冻柠檬飞冰走茶2 小时前
PTA基础编程题目集 7-19 支票面额(C语言实现)
c语言·开发语言·数据结构·算法
船漏了就会沉2 小时前
状态压缩DP:小数据下的“暴力美学”
算法
你怎么知道我是队长3 小时前
计算机虚拟存储管理与页面置换算法详解
服务器·网络·算法
罗西的思考3 小时前
【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 — (14)— Teacher
人工智能·笔记·深度学习·算法·机器学习
塔能物联运维3 小时前
塔能两相液冷:600W/cm²极限能力,为下一代AI芯片预留充足散热余量
人工智能·算法·两相液冷
醉城夜风~3 小时前
手撕 C++ string:从零实现一个简易字符串类
开发语言·c++·算法
手写码匠4 小时前
华为云Flexus+DeepSeek征文|DeepSeek+RAG知识库实战:基于Flexus X实例与Dify构建企业级智能问答系统
人工智能·深度学习·算法·aigc
青山木4 小时前
Hot 100 --- 组合总和
java·数据结构·算法·leetcode