3 冒泡排序
个人认为冒泡排序比较好理解。顾名思义,就是水里的泡泡会浮上来,在桶里达成排序效果。
原理(升序):每次比较相邻两个数,如果前面的数更大,就将这两个数调换位置。直到无法调换即为排序结束。
例子(升序):
原序列:
\(5 9 3 8\)
遍历第一次,每次比较相邻两个数,如果前面的数更大,就将这两个数调换位置后:
\(5 3 8 9\)(\(9\) 先和 \(3\) 调换位置,再和 \(8\) 调换位置)
遍历第二次,每次比较相邻两个数,如果前面的数更大,就将这两个数调换位置后:
\(3 5 8 9\)(\(5\) 和 \(3\) 调换位置)
遍历第三次后,发现没有相邻的两个数可以调换,排序结束。
代码实现:
while(1){
bool f=0;//标记有没有相邻的两个数可以调换
for(int i=1; i<n; i++){
if(a[i]>a[i+1]){
swap(a[i],a[i+1]);
f=1;//说明这一次遍历使得一些数调换了位置
}
}
if(f==0){//说明没有相邻的两个数可以调换
break;
}
}
4 计数排序
计数排序的工作原理是使用一个额外的数组 \(𝐶\),其中第 \(𝑖\) 个元素是待排序数组 \(𝐴\) 中值等于 \(𝑖\) 的元素的个数,然后根据数组 \(𝐶\) 来将 \(𝐴\) 中的元素排到正确的位置.(摘自 OI Wiki)
说简单点,就是用一个计数数组存储每个值的出现次数,然后遍历每次出现过的值。我们暂时将这个值设为 \(x\),次数设为 \(y\),则在排序数组的末尾插入 \(y\) 个 \(x\)。(对于升序,降序同理可得)
例子(升序):
原序列:\(114514\)
计数数组:
| 原序列中元素的值 | 该值出现次数 |
|---|---|
| \(1\) | \(3\) |
| \(4\) | \(2\) |
| \(5\) | \(1\) |
那么排序数组则由 \(3\) 个 \(1\),\(2\) 个 \(4\),\(1\) 个 \(5\) 组成,即 \(111445\)。
代码实现
int ma=-1,cnt[100005]={};//这里的数组大小有原序列最大的数来定,太大就不能用这种排序方法。
for(int i=1; i<=n; i++){
cnt[a[i]]++;
ma=max(ma,a[i]);
}
vector<int> b;
for(int i=1; i<=ma; i++){
for(int j=1; j<=cnt[i]; j++){
b.push_back(i);
}
}
时间复杂度 \(O(n+w)\),其中 \(w\) 为 \(a\) 中的最大值。它是一种稳定的排序算法。
浙公网安备 33010602011771号