P1177 【模板】排序
ice_fish01 · · 题解
\text{P1177} 【模板】排序
前言
- 本题解是按照 @览遍千秋的要求编写。
- 在这里,你可以领悟到 STL 的妙处,
并深深的爱上它。
20 分做法:选择排序
选择排序是一种简单直观的排序算法。它的工作原理是每次找出第
选择排序具有不稳定的特点,最优时间复杂度、平均时间复杂度和最坏时间复杂度均为
由于这种做法复杂度太高,且用起来太差劲,直接贴上代码,仅供参考:
#include <bits/stdc++.h>
using namespace std;
template<typename T> //这里没什么用的快读
inline void read(T &x) {
x = 0;
int f = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-')
f = -1;
c = getchar();
}
while (isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
x *= f;
}
template<typename T, typename ... Args>
inline void read(T &x, Args &... y) {
read(x);
read(y...);
}
int n, a[100010];
signed main() {
read(n);
for (int i = 1; i <= n; i++)
read(a[i]);
for (int i = 1; i < n; i++) {
int ith = i;
for (int j = i + 1; j <= n; j++) {
if (a[j] < a[ith])
ith = j;
}
swap(a[i], a[ith]);
}
for (int i = 1; i <= n; i++)
cout << a[i] << ' ';
return 0;
}
60 分做法:冒泡排序、桶排序
冒泡排序
冒泡排序是一种简单的排序算法。由于在算法的执行过程中,较小的元素像是气泡般慢慢「浮」到数列的顶端,故叫做冒泡排序。
它的工作原理是每次检查相邻两个元素,如果前面的元素与后面的元素满足给定的排序条件,就将相邻两个元素交换。当没有相邻的元素需要交换时,排序就完成了。可以证明,冒泡排序最多需要扫描
冒泡排序是一种稳定的排序算法,平均时间复杂度为
#include <bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T &x) {
x = 0;
int f = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-')
f = -1;
c = getchar();
}
while (isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
x *= f;
}
template<typename T, typename ... Args>
inline void read(T &x, Args &... y) {
read(x);
read(y...);
}
int n, a[100010];
signed main() {
read(n);
for (int i = 1; i <= n; i++)
read(a[i]);
bool flag = true;
while (flag) { // 还未满足有序
flag = false;
for (int i = 1; i < n; i++) {
if (a[i] > a[i + 1]) {
flag = true; // 交换后需要继续排序过程
swap(a[i], a[i + 1]); // 交换两个元素
}
}
}
for (int i = 1; i <= n; i++)
cout << a[i] << ' ';
return 0;
}
计数排序
友情提示:本部分我采用了 STL 中的 map 实现,请不懂 map 的同学到下面去看正解。
#include <bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T &x) {
x = 0;
int f = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-')
f = -1;
c = getchar();
}
while (isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
x *= f;
}
template<typename T, typename ... Args>
inline void read(T &x, Args &... y) {
read(x);
read(y...);
}
map <int, int> t;
int n, a, maxi = -1;
signed main() {
read(n);
for (int i = 1; i <= n; i++) {
read(a);
t[a]++;
maxi = max(maxi, a); // 取数列最大值,这样遍历 map 时可以减少时间
}
for (int i = 1; i <= maxi; i++) {
for (int j = 1; j <= t[i]; j++)
cout << i << ' ';
}
return 0;
}
正解:sort 排序
sort排序是algorithm头文件中自带的一个函数。- 它可以对数组中任意一段按照你的方式进行排序。
- 用法:
sort(a+1,a+n+1)或sort(a+1,a+n+1,cmp)。其中a 是数组名,它可以将a 数组中a_1\sim a_n 的这一部分排序。 - 其中
cmp是比较函数,返回值应是true或false。它可以接受两个元素a,b ,返回true代表a 应该排在b 之前,反之也成立。 - C++11 标准以及后续标准要求它的最坏时间复杂度达到
O(n\log n) 。
代码如下:
//P1177 【模板】快速排序
#include <bits/stdc++.h>
using namespace std;
int a[100010];
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++)
cout << a[i] << ' ';
return 0;
}
引用
- OI-Wiki 排序 中的部分内容。