序
基本排序主要包括,推荐排序方法使用std库sort函数
cin,cout加速——ios::sync_with_stdio(false) ,cin.tie(0) ,cout.tie(0);
P1177 【模板】排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P1177 【模板】 排序 - Flanksy - 洛谷博客 (luogu.com.cn)
一、选择排序
思路:从n个数中比较出最小的数,放到数组最前面,再从n-1个数中比较出最小的数......
时间复杂度:O(),适用于n<=1000
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
std::ios::sync_with_stdio(false);
int a[10001]={0};
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
int temp=i;
if(a[j]<a[temp]){
temp=j;
}
swap(a[i],a[temp]);
}
}
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
return 0;
}
披萨ps:分块处理......咕咕咕 咱还不太会
二、冒泡排序
思路:比较相邻的两个数,如果左边那个比右边那个大,就交换,使最大的移动至最右端 bull~(所以就叫冒泡咯)
时间复杂度:O(),最好O(n)
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
std::ios::sync_with_stdio(false);
int a[10001]={0};
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=n-1;i>=0;i--){
for(int j=0;j<i;j++){
if(a[j]>a[j+1]){
swap(a[j],a[j+1]);
}
}
}
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
return 0;
}
交换次数问题即冒泡排序交换次数,要求从小到大,则前面有几个数比a大就要交换多少次
树状数组求逆序对? 咕咕咕咕咕....
例题:
从序列第i个位置移动到第j个位置需要移动j-i次,对于第j个奇数来说,它要移动到2*j-1的位置。比如,对于第3个奇数,它应该在排完序后放在第5个位置。
三、插入排序
思路:两重循环,一重遍历n个数,另一重遍历i之前的数,找到一个合适的位置插入进去
时间复杂度:O()
#include<iostream>
using namespace std;
const int MAXN = 100001;
int main() {
float a[MAXN], temp;
int n, i, j, k;
cin >> n;
for (i = 0; i < n; i++) {
cin >> a[i];
}
for (i = 0; i < n; i++) {
for (j = i - 1; j >= 0; j--) {
if (a[j] < a[i]) {
break;
}
} //<--attention!!!!
if (j != i - 1) {
temp = a[i];
for (k = i - 1; k > j; k--) {
a[k + 1] = a[k];
}
a[k + 1] = temp;
}
}
for (i = 0; i < n; i++) {
cout << a[i] << " ";
}
return 0;
}
四、简易版桶排序
思路:开一个数组c [ n ]初始值都为0,输入到a [ i ],c [ a [ i ] ]++
时间复杂度:O(n+w),只能给小于的数排序
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=100001;
const int K=1001;
int main()
{
int n;
cin>>n;
int a[MAXN];
int c[K];
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
c[a[i]]+=1;
}
for(int i=0;i<K;i++){
for(int j=0;j<c[i];j++){
cout<<i<<" ";
}
}
return 0;
}
五、快速排序
思路:取数组中间的一个数mid,小于mid的放到b数组,等于mid的放到c数组,大于mid的放到d数组,再排序b,d数组。递归退出条件:l>=r。
时间复杂度:最好O() 最坏O()
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int n;
long long int a[100001],b[100001],c[100001],d[100001],t[100001];
int randint(int l,int r){
return rand()%(r-l+1)+l;
}
void qsort(int l,int r){
if(l>=r){
return;
}
int num=randint(l,r);//采用二分能够减少内存
int ind1=0,ind2=0,ind3=0;
for(int i=l;i<=r;i++){
if(a[i]<a[num]){
b[ind1++]=a[i];
}
if(a[i]==a[num]){
c[ind2++]=a[i];
}
if(a[i]>a[num]){
d[ind3++]=a[i];
}
}
for(int i=0;i<ind1;i++){
a[i+l]=b[i];
}
for(int i=0;i<ind2;i++){
a[i+l+ind1]=c[i];
}
for(int i=0;i<ind3;i++){
a[i+l+ind1+ind2]=d[i];
}
qsort(l,l+ind1-1);
qsort(l+ind1+ind2,r);
}
int main(){
srand(time(NULL));
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
qsort(0,n-1);
//去重
int i=0,j=0,counter=0;
while(i<n){
if(a[i]!=a[++j]){
t[counter++]=a[i];
i=j;
}
}
cout<<counter<<endl;
for(int i=0;i<counter;i++){
cout<<t[i]<<" ";
}
}
快速排序运用分治,可修改其中某些过程,完成特定目标
六、sort函数
库文件algorithm sort(a,a+n,cmp)
cmp函数可自己定义,在结构体排序中用处更大,强烈推荐
样例:
#include<iostream>
#include<algorithm>
using namespace std;
struct person{
string name;
int a,d; //a攻击力,d防御力
};
bool cmp(person jack,person rose){
if(jack.a==rose.a){
return jack.d>rose.d; //攻击力相同就比防御力
}
return jack.a>rose.a;
}
person p[10005];
int main(){
int t;
cin>>t;
for(int o=0;o<t;o++){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>p[i].name>>p[i].a>>p[i].d;
}
sort(p,p+n,cmp);
for(int i=0;i<m;i++){
cout<<p[i].name<<endl;
}
}
return 0;
}
七、使用vector的sort排序与去重
vector为stl函数中类似数组的一种容器,可以存放各类数据,并且相较于数组不用确定大小,具有更便捷的修改,增添,存储功能。vector<int> a 即为定义了一个叫a的vector。
a.erase(pos)为删除pos位置的元素,a.erase(beg,end)为删除这一区间的元素
unique(beg,end)为去重这一区间内相邻的重复元素(所以需要先进行排序),此去重最终返回的是去重完后序列的最后一元素的地址(也是去重后的元素个数),重复的元素并没有被删掉,只是被排到最后去了。例如v{1,2,3,5,2,1},sort排序后v{1,1,2,2,3,5},unique去重后v{1,2,3,5,1,2},返回值为第二个1的地址。a.erase(unique(a.begin(), a.end()), a.end())即为删除了最后那两个1,2
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> a;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
a.push_back(x);
}
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
for (auto &i : a)cout << i << " ";
}
八、堆排序(咕咕咕中)
看了一眼,但是我不懂,并且大为震撼