计数排序 -- GoLang实现

本文介绍了一种简单有效的排序算法——计数排序。该算法适用于输入元素位于0到k区间内的整数,通过统计每个元素的个数并计算排名来完成排序。文章详细解释了其工作原理、伪代码实现及Golang源码,并分析了时间复杂度和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前提假设
  假设 n 个输入元素中每一个都是在 0 到 k 区间内的一个整数,其中 k 为某个整数。

基本思想
  对每一个输入元素 x,确定小于 x 的元素个数。然后利用这个值,可以直接把 x 放到它在输出数组中的位置。

例如
  对数组 [ 2, 5, 3, 0, 2, 4, 0, 3 ] 进行计数排序,其中小于 4 的元素有 6 个,那么 4 应该放在第 7 个输出位置上。

伪代码实现:
说明:假设输入是一个数组 A[ 1 … n ], A.length = n。还需要另外两个数组
  B[ 1…n ]: 存放最终排序的输出
  C[ 1…k ]: 提供临时存储空间,用于统计数组 A 中每个元素的个数和统计数组 A 中每个元素 x 的排名(即小于 x 的元素个数)

COUNTER-SORT(A, B, k)
let C[0..k] be a new array
for i = 0 to k
	C[i] = 0
for j = 1 to A.length
	C[A[j]] = C[A[j]] + 1
// C[i] now contains the number of elements equal to i.
for i = 1 to k
	C[i] = C[i] + C[i - 1]
// C[i] now contains the numer of elements less than or equal to i.
for j = A.length downto 1
	B[C[A[j]]] = A[j]
	C[A[j]] = C[A[j]] - 1

Golang源码实现:

// CounterSort 计数排序
func CounterSort(A, B []int, k int) {
	LengthA := len(A)
	C := make([]int, k+1)
	for i := 0; i < LengthA; i++ {
		C[A[i]]++
	}
	for j := 1; j < k+1; j++ {
		C[j] += C[j-1]
	}
	for l := LengthA - 1; l >= 0; l-- {
		B[C[A[l]]-1] = A[l]
		C[A[l]]--
	}
}

算法分析:
时间复杂度:
  第5 ~ 7行的for循环和11 ~ 14的for循环耗时为 O(n),第8 ~ 10 行的for 循环耗时为 O(k)。所以算法的时间复杂度为 O( n + k)。
稳定性:计数排序是稳定排序,其稳定性依赖于最后一次遍历的for循环是 从后往前遍历数组 A 的,并且每次填充了一个元素后,C[ A[ l ] ] 执行自减操作。意味着当出现相同元素时,该相同的元素会被放到另一个相同元素的前面,即保持了稳定性。

问题延伸:
请设计一个算法,它能够对于任何给定的介于 0 到 k 之间的 n 个整数先进行预处理,然后在 O(1) 的时间内回答输入 n 个整数中有多少个落在区间 [ a … b ] 内。你设计的算法的预处理时间应为 O( n + k )。
评论区留下你的想法吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值