2
2
3
3
计数排序:统计小于等于该元素值的元素的个数i,于是该元素就放在目标数组的索引i位(i≥0)。
4
4
5
- 计数排序基于一个假设,待排序数列的所有数均出现在(0,k)的区间之内,如果k过大则会引起较大的空间复杂度
6
- 计数排序并非是一种基于比较的排序方法,它直接统计出键值本应该出现的位置
7
- 时间复杂度为O(n),空间复杂度为O(n+k)
5
+ 计数排序基于一个假设,待排序数列的所有数均为整数,且出现在(0,k)的区间之内。
6
+ 如果 k(待排数组的最大值) 过大则会引起较大的空间复杂度,一般是用来排序 0 到 100 之间的数字的最好的算法,但是它不适合按字母顺序排序人名。
7
+ 计数排序不是比较排序,排序的速度快于任何比较排序算法。
8
+ 时间复杂度为 O(n+k),空间复杂度为 O(n+k)
9
+
10
+ 算法的步骤如下:
11
+
12
+ 1. 找出待排序的数组中最大和最小的元素
13
+ 2. 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项
14
+ 3. 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加)
15
+ 4. 反向填充目标数组:将每个元素 i 放在新数组的第 C[i] 项,每放一个元素就将 C[i] 减去 1
8
16
9
17
*****************/
10
18
11
19
12
- #include < iostream>
13
- #include < vector>
20
+ #include < iostream>
21
+ #include < vector>
22
+ #include < algorithm>
14
23
15
24
using namespace std ;
16
25
17
- void countSort (vector<int >& vec,vector<int >& objVec)
26
+ // 计数排序
27
+ void CountSort (vector<int >& vecRaw, vector<int >& vecObj)
18
28
{
19
- vector<int > range (10 ,0 ); // range的下标即键值
20
- for (int i=0 ;i<vec.size ();++i)
21
- {// 统计每个键值出现的次数
22
- range[vec[i]]++;
23
- }
24
-
25
- for (int i=1 ;i<vec.size ();++i)
26
- {// 后面的键值出现的位置为前面所有键值出现的次数之和
27
- range[i]+=range[i-1 ];
28
- }
29
- // 至此,range中存放的是相应键值应该出现的位置
30
- int length=vec.size ();
31
- for (int i=length-1 ;i>=0 ;--i) // 注意一个小细节,统计时最正序的,这里是逆序
32
- {// 如果存在相同的键值,为了保持稳定性,后出现的应该还是位于后面
33
- // 如果正序,则先出现的会放置到后面,因此不再稳定
34
- objVec[range[vec[i]]]=vec[i]; // 将键值放到目标位置
35
- range[vec[i]]--;
36
- }
29
+ // 确保待排序容器非空
30
+ if (vecRaw.size () == 0 )
31
+ return ;
32
+
33
+ // 使用 vecRaw 的最大值 + 1 作为计数容器 countVec 的大小
34
+ int vecCountLength = (*max_element (begin (vecRaw), end (vecRaw))) + 1 ;
35
+ vector<int > countVec (vecCountLength, 0 );
36
+
37
+ // 统计每个键值出现的次数
38
+ for (int i = 0 ; i < vecRaw.size (); i++)
39
+ countVec[vecRaw[i]]++;
40
+
41
+ // 后面的键值出现的位置为前面所有键值出现的次数之和
42
+ for (int i = 1 ; i < vecCountLength; i++)
43
+ countVec[i] += countVec[i - 1 ];
44
+
45
+ // 将键值放到目标位置
46
+ for (int i = vecRaw.size (); i > 0 ; i--) // 此处逆序是为了保持相同键值的稳定性
47
+ vecObj[--countVec[vecRaw[i - 1 ]]] = vecRaw[i - 1 ];
37
48
}
38
49
39
50
int main ()
40
51
{
41
- int a[14 ]={0 ,5 ,7 ,9 ,6 ,3 ,4 ,5 ,2 ,8 ,6 ,9 ,2 ,1 };
42
- vector<int > vec (a,a+14 );
43
- vector<int > objVec (14 ,0 );
44
-
45
- countSort (vec,objVec);
52
+ vector<int > vecRaw = { 0 ,5 ,7 ,9 ,6 ,3 ,4 ,5 ,2 ,8 ,6 ,9 ,2 ,1 };
53
+ vector<int > vecObj (vecRaw.size (), 0 );
46
54
47
- for (int i=0 ;i<objVec.size ();++i)
48
- cout<<objVec[i]<<" " ;
49
- cout<<endl;
55
+ CountSort (vecRaw, vecObj);
50
56
57
+ for (int i = 0 ; i < vecObj.size (); ++i)
58
+ cout << vecObj[i] << " " ;
59
+ cout << endl;
60
+
51
61
return 0 ;
52
62
}
0 commit comments