-
计数排序:
-
假设:如果要排序的项目是小范围的整数,我们可以计算每个整数(在这个小范围内)的出现频率(O(N)),然后通过循环该小范围来按排序顺序输出项目。
-
在示例数组{2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4, 2, 4, 6, 9, 2}中,对所有整数都在[1..9]内的示例数组尝试Counting Sort,因此我们只需要计算整数1出现的次数,出现整数2,…,出现整数9,然后遍历 如果频率 [y] = x,则 1至9 打印出整数 y 的 x 个副本。
-
时间复杂度为O(N)来计算频率,O(N + k)以排序顺序输出结果,其中 k 是输入的整数范围,在本例中为9-1 + 1 = 9。 计数排序(Counting Sort)的时间复杂度为O(N + k),如果 k 很小,那么它就是O(N)。
-
由于内存限制,当 k 相对较大时,我们将无法执行计数排序(Counting Sort)的计数部分,因为我们需要存储那些 k 个整数出现的次数。
-
-
代码:
int CountingSort(int *data_arr, int data_num)
{
int ret = 0;
int data_index = 0, count_index = 0;
/*
1. data_arr = {2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4, 2, 4, 6, 9, 2}
2. 计数数组的成员个数,为原始数组中最大的元素值。
*/
int count_arr[10] = {0};
int count_num = sizeof(count_arr) / sizeof(count_arr[0]);
int *pai_arr = NULL;
pai_arr = malloc(sizeof(int) * data_num);
if (NULL == pai_arr) {
return;
}
memset(pai_arr, 0, sizeof(int) * data_num);
/*
1. 计数数组每个索引位置存储的是,与该索引值相等的原始数组中元素的个数。
2. 操作后,count_arr = {0, 2, 7, 2, 2, 0, 1, 2, 2, 2}
*/
memset(count_arr, 0, sizeof(count_arr));
for (data_index = 0; data_index < data_num; data_index++) {
count_arr[ data_arr[data_index] ] += 1;
}
/*
1. 计数数组每个索引位置存储的是,大于等于该索引值的原始数组中元素的个数。
2. 操作后,count_arr = {0, 2, 9, 11, 13, 13, 14, 16, 18, 20}
*/
for (count_index = 1; count_index < count_num; count_index++) {
count_arr[count_index] += count_arr[count_index - 1];
}
/* 逆序遍历原始数组,根据元素值(value),
找到大于等于该元素值(value)的元素个数(pos),
将元素值存储在新数组中的正确位置上。 */
for (data_index = data_num - 1; data_index >= 0; data_index--) {
int value = data_arr[data_index];
int pos = count_arr[value];
pai_arr[pos - 1] = value;
count_arr[value] -= 1;
}
for (data_index = 0; data_index < data_num; data_index++) {
data_arr[data_index] = pai_arr[data_index];
}
if (NULL != pai_arr) {
free(pai_arr);
pai_arr = NULL;
}
return ret;
}
版权声明:本文为liufuchun111原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。