计数排序是一种非比较排序算法,主要用于整数排序。计数排序的基本思想是,对于给定的输入序列中的每一个元素 x,确定小于 x 的元素个数。利用这一信息,可以直接把 x 放到它在输出序列中的位置上。
计数排序的步骤如下:
-
找出待排序的数组中最大和最小的元素;
-
统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;
-
对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);
-
反向填充目标数组:将每个元素 i 放在新数组的第 C(i) 项,每放一个元素就将 C(i) 减去 1。
计数排序的时间复杂度为 O(n + k),其中 k 表示数据范围。虽然时间复杂度比较小,但计数排序的缺点是它只能用于整数排序,而且当数据范围很大时,需要大量的辅助空间。计数排序是一种非比较排序算法,主要用于整数排序。计数排序的基本思想是,对于给定的输入序列中的每一个元素 x,确定小于 x 的元素个数。利用这一信息,可以直接把 x 放到它在输出序列中的位置上。
计数排序的步骤如下:
-
找出待排序的数组中最大和最小的元素;
-
统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;
-
对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);
-
反向填充目标数组:将每个元素 i 放在新数组的第 C(i) 项,每放一个元素就将 C(i) 减去 1。
计数排序的时间复杂度为 O(n + k),其中 k 表示数据范围。虽然时间复杂度比较小,但计数排序的缺点是它只能用于整数排序,而且当数据范围很大时,需要大量的辅助空间。
一、C 实现 计数排序 及代码详解
计数排序(Counting Sort)是一种线性时间复杂度的排序算法,它的基本思想是统计每个元素出现的次数,然后根据元素的值和出现次数直接计算每个元素的位置。
计数排序适用于待排序的元素范围比较小的情况,时间复杂度为 O(n+k),其中 k 是待排序元素的范围大小。如果 k 太大,则会导致排序时间过长和占用过多的内存空间,此时不适合使用计数排序。
以下是 C 语言实现计数排序的代码及注释:
#include <stdio.h>
#include <stdlib.h>
/* 计数排序函数,arr为待排序数组,n为数组大小 */
void counting_sort(int arr[], int n)
{
int max_element = 0;
int i, j;
/* 找到最大值,确定桶的大小 */
for (i = 0; i < n; i++) {
if (arr[i] > max_element) {
max_element = arr[i];
}
}
/* 创建桶 */
int *count = (int*)calloc(max_element + 1, sizeof(int));
/* 统计每个元素出现的次数 */
for (i = 0; i < n; i++) {
count[arr[i]]++;
}
/* 对桶进行求和操作 */
for (i = 1; i <= max_element; i++) {
count[i] += count[i - 1];
}
/* 定义一个临时数组,用于存储排好序的结果 */
int *sorted = (int*)malloc(n * sizeof(int));
/* 根据桶的统计结果排序 */
for (i = n - 1; i >= 0; i--) {
sorted[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}
/* 将排序好的结果拷贝回原数组 */
for (i = 0; i < n; i++) {
arr[i] = sorted[i];
}
/* 释放内存 */
free(count);
free(sorted);
}
int main()
{
int arr[] = {8, 2, 3, 5, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int i;
counting_sort(arr, n);
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
计数排序的核心代码包括四个部分:
- 找到最大值,确定桶的大小;
- 创建桶,并统计每个元素出现的次数;
- 对桶进行求和操作,得到每个元素的位置;
- 根据桶的统计结果排序,并将排序好的结果拷贝回原数组。
这里需要注意的是,由于计数排序的桶大小取决于待排序元素的最大值,因此需要使用动态内存分配来创建桶,并在排序结束后释放内存。同时,在排序过程中需要使用一个临时数组来存储排好序的结果。
最后,在 main 函数中调用 counting_sort 函数,并打印排序后的结果。计数排序(Counting Sort)是一种线性时间复杂度的排序算法,它的基本思想是统计每个元素出现的次数,然后根据元素的值和出现次数直接计算每个元素的位置。
计数排序适用于待排序的元素范围比较小的情况,时间复杂度为 O(n+k),其中 k 是待排序元素的范围大小。如果 k 太大,则会导致排序时间过长和占用过多的内存空间,此时不适合使用计数排序。
以下是 C 语言实现计数排序的代码及注释:
#include <stdio.h>
#include <stdlib.h>
/* 计数排序函数,arr为待排序数组,n为数组大小 */
void counting_sort(int arr[], int n)
{
int max_element = 0;
int i, j;
/* 找到最大值,确定桶的大小 */
for (i = 0; i < n; i++) {
if (arr[i] > max_element) {
max_element = arr[i];
}
}
/* 创建桶 */
int *count = (int*)calloc(max_element + 1, sizeof(int));
/* 统计每个元素出现的次数 */
for (i = 0; i < n; i++) {
count[arr[i]]++;
}
/* 对桶进行求和操作 */
for (i = 1; i <= max_element; i++) {
count[i] += count[i - 1];
}
/* 定义一个临时数组,用于存储排好序的结果 */
int *sorted = (int*)malloc(n * sizeof(int));
/* 根据桶的统计结果排序 */
for (i = n - 1; i >= 0; i--) {
sorted[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}
/* 将排序好的结果拷贝回原数组 */
for (i = 0; i < n; i++) {
arr[i] = sorted[i];
}
/* 释放内存 */
free(count);
free(sorted);
}
int main()
{
int arr[] = {8, 2, 3, 5, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int i;
counting_sort(arr, n);
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
计数排序的核心代码包括四个部分:
- 找到最大值,确定桶的大小;
- 创建桶,并统计每个元素出现的次数;
- 对桶进行求和操作,得到每个元素的位置;
- 根据桶的统计结果排序,并将排序好的结果拷贝回原数组。
这里需要注意的是,由于计数排序的桶大小取决于待排序元素的最大值,因此需要使用动态内存分配来创建桶,并在排序结束后释放内存。同时,在排序过程中需要使用一个临时数组来存储排好序的结果。
最后,在 main 函数中调用 counting_sort 函数,并打印排序后的结果。
二、C++ 实现 计数排序 及代码详解
计数排序(Counting Sort)是一种非比较排序算法,其思想是先统计待排序序列中每个元素出现的次数,然后根据元素大小依次在输出序列中放置相应个数的元素。
1.算法步骤
- 统计待排序序列中每个元素出现的次数,得到计数数组 C。
- 对计数数组 C 进行前缀和运算,得到累加数组 D,其中 D[i] 表示序列中不大于 i 的元素个数。
- 倒序遍历原序列,根据元素在累加数组 D 中的对应位置进行元素放置,同时减少计数数组 C 中对应元素的值,以便后续相同元素的正确放置。
2.代码实现
计数排序的时间复杂度为 O(n+k),其中 n 为序列长度,k 为元素取值范围(即序列中最大元素的值加一)。以下是 C++ 实现的代码:
void countingSort(vector<int>& arr) {
if (arr.empty()) {
return;
}
int max_val = *max_element(arr.begin(), arr.end());
vector<int> cnt(max_val + 1, 0);
for (int num : arr) {
cnt[num]++;
}
for (int i = 1; i <= max_val; i++) {
cnt[i] += cnt[i - 1];
}
vector<int> res(arr.size(), 0);
for (int i = arr.size() - 1; i >= 0; i--) {
res[cnt[arr[i]] - 1] = arr[i];
cnt[arr[i]]--;
}
arr = res;
}
3.代码解释
- 第 2~5 行:判断输入数组是否为空,若为空则直接返回。
- 第 6 行:获取输入数组中的最大值 max_val,用于初始化计数数组。
- 第 7~9 行:初始化计数数组 cnt,统计输入数组中每个元素出现的次数。
- 第 10~12 行:对计数数组 cnt 进行前缀和运算,得到累加数组 cnt,其中 cnt[i] 表示序列中不大于 i 的元素个数。
- 第 13 行:初始化输出数组 res。
- 第 14~17 行:倒序遍历输入数组 arr,根据元素在累加数组 cnt 中的对应位置进行元素放置,同时减少计数数组 cnt 中对应元素的值,以便后续相同元素的正确放置。
- 第 18 行:将排序后的结果存储回原始数组 arr。计数排序(Counting Sort)是一种非比较排序算法,其思想是先统计待排序序列中每个元素出现的次数,然后根据元素大小依次在输出序列中放置相应个数的元素。
1.算法步骤
- 统计待排序序列中每个元素出现的次数,得到计数数组 C。
- 对计数数组 C 进行前缀和运算,得到累加数组 D,其中 D[i] 表示序列中不大于 i 的元素个数。
- 倒序遍历原序列,根据元素在累加数组 D 中的对应位置进行元素放置,同时减少计数数组 C 中对应元素的值,以便后续相同元素的正确放置。
2.代码实现
计数排序的时间复杂度为 O(n+k),其中 n 为序列长度,k 为元素取值范围(即序列中最大元素的值加一)。以下是 C++ 实现的代码:
void countingSort(vector<int>& arr) {
if (arr.empty()) {
return;
}
int max_val = *max_element(arr.begin(), arr.end());
vector<int> cnt(max_val + 1, 0);
for (int num : arr) {
cnt[num]++;
}
for (int i = 1; i <= max_val; i++) {
cnt[i] += cnt[i - 1];
}
vector<int> res(arr.size(), 0);
for (int i = arr.size() - 1; i >= 0; i--) {
res[cnt[arr[i]] - 1] = arr[i];
cnt[arr[i]]--;
}
arr = res;
}
3.代码解释
- 第 2~5 行:判断输入数组是否为空,若为空则直接返回。
- 第 6 行:获取输入数组中的最大值 max_val,用于初始化计数数组。
- 第 7~9 行:初始化计数数组 cnt,统计输入数组中每个元素出现的次数。
- 第 10~12 行:对计数数组 cnt 进行前缀和运算,得到累加数组 cnt,其中 cnt[i] 表示序列中不大于 i 的元素个数。
- 第 13 行:初始化输出数组 res。
- 第 14~17 行:倒序遍历输入数组 arr,根据元素在累加数组 cnt 中的对应位置进行元素放置,同时减少计数数组 cnt 中对应元素的值,以便后续相同元素的正确放置。
- 第 18 行:将排序后的结果存储回原始数组 arr。
三、Java 实现 计数排序 及代码详解
计数排序是一种非比较排序算法,它的基本思想是利用一个辅助数组来记录每个元素出现的次数,然后再将辅助数组中的元素依次累加,得到每个元素在排序后的序列中的位置。具体实现步骤如下:
-
找到待排序序列中的最大值和最小值。
-
建立一个辅助数组,数组长度为最大值和最小值之间的差值加一。
-
遍历待排序序列,将每个元素出现的次数记录在辅助数组中。
-
根据辅助数组计算每个元素在排序后的序列中的位置,存储到一个新的数组中。
下面是 Java 实现计数排序的代码及注释:
public static void countingSort(int[] arr) {
// 找到待排序序列中的最大值和最小值
int max = arr[0], min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
// 建立一个辅助数组
int[] count = new int[max - min + 1];
// 遍历待排序序列,将每个元素出现的次数记录在辅助数组中
for (int i = 0; i < arr.length; i++) {
count[arr[i] - min]++;
}
// 根据辅助数组计算每个元素在排序后的序列中的位置
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
// 存储排序后的元素到一个新的数组中
int[] sortedArr = new int[arr.length];
for (int i = arr.length - 1; i >= 0; i--) {
sortedArr[count[arr[i] - min] - 1] = arr[i];
count[arr[i] - min]--;
}
// 将排序后的数组赋值给原数组
for (int i = 0; i < arr.length; i++) {
arr[i] = sortedArr[i];
}
}
以上就是 Java 实现计数排序的代码及注释。计数排序是一种非比较排序算法,它的基本思想是利用一个辅助数组来记录每个元素出现的次数,然后再将辅助数组中的元素依次累加,得到每个元素在排序后的序列中的位置。具体实现步骤如下:
-
找到待排序序列中的最大值和最小值。
-
建立一个辅助数组,数组长度为最大值和最小值之间的差值加一。
-
遍历待排序序列,将每个元素出现的次数记录在辅助数组中。
-
根据辅助数组计算每个元素在排序后的序列中的位置,存储到一个新的数组中。
下面是 Java 实现计数排序的代码及注释:
public static void countingSort(int[] arr) {
// 找到待排序序列中的最大值和最小值
int max = arr[0], min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
// 建立一个辅助数组
int[] count = new int[max - min + 1];
// 遍历待排序序列,将每个元素出现的次数记录在辅助数组中
for (int i = 0; i < arr.length; i++) {
count[arr[i] - min]++;
}
// 根据辅助数组计算每个元素在排序后的序列中的位置
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
// 存储排序后的元素到一个新的数组中
int[] sortedArr = new int[arr.length];
for (int i = arr.length - 1; i >= 0; i--) {
sortedArr[count[arr[i] - min] - 1] = arr[i];
count[arr[i] - min]--;
}
// 将排序后的数组赋值给原数组
for (int i = 0; i < arr.length; i++) {
arr[i] = sortedArr[i];
}
}
以上就是 Java 实现计数排序的代码及注释。