-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
90 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
## 计数排序 | ||
|
||
计数排序(Counting Sort)是一种非比较性质的排序算法。它的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中,也就是说这个辅助空间的长度取决于待排序列中的数据范围(就是序列中的最大值与最小值的差加上1)。根据元素本身的值,将每个元素出现的次数记录到辅助空间后,通过对辅助空间内数据的计算,即可确定每一个元素最终的位置。 | ||
|
||
### 算法步骤 | ||
|
||
1. 找出待排序列中最大值 max 和最小值 min,根据它们的差值,申请辅助空间 C[max-min+1]; | ||
2. 遍历待排序列,统计序列中每个值为 i 的元素出现的次数,记录在辅助空间的第 i 位; | ||
3. 对辅助空间内的数据进行计算(从空间中的第一个元素开始,每一项和前一项相加),以确定值为 i 的元素在数组中出现的位置; | ||
4. 反向填充目标数组:将每个元素 i 放在目标数组的第 C[i] 位,每放一个元素就将 C[i] 减1,直到 C 中所有值都是 0 | ||
|
||
### 动图演示 | ||
|
||
![](counting-sort.gif) | ||
|
||
### 代码实现 | ||
|
||
#### C语言 | ||
```c | ||
void counting_sort(int arr[], int n) { | ||
if (arr == NULL) return; | ||
// 定义辅助空间并初始化 | ||
int max = arr[0], min = arr[0]; | ||
int i; | ||
for (i = 1; i < n; i++) { | ||
if (max < arr[i]) max = arr[i]; | ||
if (min > arr[i]) min = arr[i]; | ||
} | ||
int size = max - min + 1; | ||
int C[size]; | ||
memset(C, 0, sizeof(C)); | ||
// 定义目标数组 | ||
int R[n]; | ||
// 统计每个元素出现的次数 | ||
for (i = 0; i < n; i++) C[arr[i] - min]++; | ||
// 对辅助空间内数据进行计算 | ||
for (i = 1; i < size; i++) C[i] += C[i - 1]; | ||
// 反向填充目标数组 | ||
for (i = n - 1; i >= 0; i--) R[--C[arr[i] - min]] = arr[i]; | ||
// 目标数组里的结果重新赋值给 arr | ||
for (i = 0; i < n; i++) arr[i] = R[i]; | ||
} | ||
``` | ||
### 算法分析 | ||
计数排序属于**非交换排序**,是**稳定排序**,适合数据范围不显著大于数据数量的序列。它的时间复杂度是线性的,为 O(n+k),空间复杂度也是 O(n+k),它快于任何比较排序算法,但这是通过牺牲空间换取时间实现的。 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
void counting_sort(int arr[], int n) { | ||
if (arr == NULL) return; | ||
// 定义辅助空间并初始化 | ||
int max = arr[0], min = arr[0]; | ||
int i; | ||
for (i = 1; i < n; i++) { | ||
if (max < arr[i]) max = arr[i]; | ||
if (min > arr[i]) min = arr[i]; | ||
} | ||
int size = max - min + 1; | ||
int C[size]; | ||
memset(C, 0, sizeof(C)); | ||
// 定义目标数组 | ||
int R[n]; | ||
// 统计每个元素出现的次数 | ||
for (i = 0; i < n; i++) C[arr[i] - min]++; | ||
// 对辅助空间内数据进行计算 | ||
for (i = 1; i < size; i++) C[i] += C[i - 1]; | ||
// 反向填充目标数组 | ||
for (i = n - 1; i >= 0; i--) R[--C[arr[i] - min]] = arr[i]; | ||
// 目标数组里的结果重新赋值给 arr | ||
for (i = 0; i < n; i++) arr[i] = R[i]; | ||
} | ||
|
||
int main() { | ||
int arr[] = {2, 4, 3, 1, 4, 6, 4, 2}; | ||
int n = sizeof(arr) / sizeof(*arr); | ||
counting_sort(arr, n); | ||
printf("Sort result:\n"); | ||
for (int i = 0; i < n; i++) | ||
printf("%d ", arr[i]); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters