1. 计数排序(Counting Sort)简介
计数排序是一种非基于比较的排序算法,它通过统计每个元素的出现次数,并根据统计结果将元素排列在正确的位置上。计数排序适用于对一定范围内的整数进行排序,例如,对于给定的一组学生成绩,取值范围在0到100之间,可以使用计数排序算法快速排序。
2. 计数排序算法过程
计数排序的算法过程可以简述为以下几步:
(1)确定待排序数组的取值范围
首先,需要确定待排序数组中的元素取值范围,这样才能确定计数数组的大小。
def counting_sort(arr):
max_val = max(arr)
min_val = min(arr)
range_val = max_val - min_val + 1
count = [0] * range_val
return count, min_val
array = [4, 2, 1, 7, 3, 5, 2, 6]
counting_array, min_val = counting_sort(array)
上述代码中,我们计算了待排序数组的最大值和最小值,并得到了元素取值范围range_val
。然后,创建了一个初始全为0的计数数组count
,并返回了count
和min_val
。
(2)统计各个元素的出现次数
接下来,需要遍历待排序数组并统计每个元素的出现次数。遍历数组时,对每个元素进行减去min_val
的操作,将元素映射到计数数组的索引位置,然后将对应索引位置的计数值加1。
for num in arr:
count[num - min_val] += 1
上述代码中的num - min_val
将元素映射到计数数组中的索引位置。
(3)累加计数数组
在计数数组中,每个索引位置的元素值等于该元素所对应的元素在待排序数组中的出现次数。为了确保排序的稳定性,需要累加计数数组中每个位置的前一个位置的计数值。
for i in range(1, range_val):
count[i] += count[i - 1]
上述代码中,从索引位置1开始遍历计数数组,将当前索引位置的值加上前一个索引位置的值。
(4)生成排序后的数组
最后,根据计数数组中的统计结果,生成排序后的数组。
首先,创建一个与待排序数组相同大小的排序数组;然后从待排序数组的最后一个元素开始遍历,查找该元素在计数数组中的值(即元素在排序数组中的位置);将该元素放入排序数组中,并将计数数组对应位置的值减1。
sort_array = [0] * len(arr)
for i in range(len(arr) - 1, -1, -1):
sort_array[count[arr[i] - min_val] - 1] = arr[i]
count[arr[i] - min_val] -= 1
上述代码中,i
从待排序数组的最后一个元素开始倒序遍历,这是为了保证排序的稳定性。对于每个元素arr[i]
,通过count[arr[i] - min_val]
查找其在排序数组中的位置,将其放入排序数组中,并将计数数组对应位置的值减1。
3. 计数排序的复杂度分析
计数排序的时间复杂度可以表示为O(n+k),其中n是待排序数组的大小,k是元素取值范围的大小。计数排序的空间复杂度为O(k)。
计数排序的主要优点是在对一定范围内的整数进行排序时具有较高的效率。但是,计数排序只适用于非负整数排序,并且对于元素的取值范围较大时,计数数组可能会占用较大的空间。
4. 实例分析
为了验证计数排序的正确性和效率,我们将使用一个包含10000个元素的随机数组进行排序。
import random
import time
# 生成随机数组
array = [random.randint(0, 100) for _ in range(10000)]
# 使用计数排序进行排序
start_time = time.time()
counting_array, min_val = counting_sort(array)
sort_array = [0] * len(array)
for i in range(len(array) - 1, -1, -1):
sort_array[counting_array[array[i] - min_val] - 1] = array[i]
counting_array[array[i] - min_val] -= 1
end_time = time.time()
# 输出排序结果和排序时间
print("排序结果:", sort_array)
print("排序时间:", end_time - start_time, "s")
运行上述代码,可以得到排序结果和排序时间。根据运行结果,可以确认计数排序的正确性和较高的效率。
5. 总结
本文详细介绍了计数排序算法的原理和过程。计数排序是一种非常高效的排序算法,适用于一定范围内的整数排序。通过统计元素出现次数,可以快速获得排序结果。然而,计数排序只适用于非负整数排序,并且对于取值范围较大的数组可能会占用较大的空间。因此,在实际应用中需要根据具体情况选择合适的排序算法。