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\) 中的最大值。它是一种稳定的排序算法。

posted on 2026-07-01 16:45  lz5332t  阅读(6)  评论(0)    收藏  举报