本文写于很久之前,那时读者水平很低,本文仅供参考,建议按照更正统的道路学习排序
关于排序
排序,就是指给你一个无序的数列,让你通过某种方式把这个数列转换为有序数列。
一般情况下,以比较为基本运算的排序算法极限是nlogn(有不是很复杂的证明方法),而以非比较为基本运算的算法多是线性(当然也有很多局限)
本文主要讲解一个 令人感动的稳定
n
2
n^{2}
n2算法(冒泡)、两个nlogn算法(快速排序sort,堆排序)以及线性排序基本原理和代表计数(无误)排序
本文所有排序以升序为例
冒泡排序
最简单的排序,没有之一。
原理为对于每一个元素,与它之前的所有元素比较大小,小则交换。
没了。
#include<bits/stdc++.h>
using namespace std;
int a[10001];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
if(a[i]<a[j])
swap(a[i],a[j]);//cmath自带函数,交换两个数
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
nlogn算法
快排sort
其实我认为我当初真是闲的学快排学那么认真,不知道sort大法万岁
首先,快排能解决的一切问题,sort都能解决
sort原理:通过一些令人窒息的骚操作,以我们看不懂的方式,针对每一组待排序数据选择合适的算法进行排序。(比如什么时候用插入,什么时候用快排,什么时候用堆排)
#include<bits/stdc++.h>
using namespace std;
int a[10001];
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;
}
sort排序默认升序,如果你想降序,就用下面的程序
#include<bits/stdc++.h>
using namespace std;
int a[10001];
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
sort(a+1,a+n+1,cmp);
a+1:这里指a数组的起始地址,因为我习惯数组下标从1开始,所以是 a+1。
a+n+1:n指的是数组长度,+1原因与上一致。
cmp:比较器,如果你排序的a数组是c++自带的(就是int那些关键字定义的),那么比较器可以不写,它会默认加上升序比较器。如果你想降序或者给结构体排序,就得写cmp,cmp的意义是告诉sort以什么样的标准排序。
堆排序
首先,你得知道什么是堆
来进行排序。
小根堆堆顶元素最小,我们只需要每次插入元素,确保插入后堆依然是小根堆就可以了,每次弹出堆顶。
你可能会说:堆排序也太麻烦了吧,还得手写堆,再balabala一大堆
这都9102年了还有人不会用stl呢
上面我的这篇博客讲的很详尽了,值得好好学习。
#include<bits/stdc++.h>
using namespace std;
struct node{
int x;
inline bool operator<(const node a)const
{
return x>a.x;//重载运算符固定格式,重新解释<的意义
}
};
priority_queue<node>q;
int main()
{
int n;
cin>>n;
int a;
for(int i=1;i<=n;i++)
{
cin>>a;
q.push((node){a});
}
node step;
for(int i=1;i<=n;i++)
{
step=q.top();
q.pop();
cout<<step.x<<" ";
}
return 0;
}
这个代码带了重载运算符,是升序排序。
线性排序
基本原理
通过统计一些信息,使得每个数彼此都能区分,统计出每个数出现几次,从小到大,出现几次就输出几次,每出现就不输出
计(无误)数排序
#include<bits/stdc++.h>
using namespace std;
int a[10001];
int main()
{
int n;
cin>>n;
int x;
int maxn=-1e9;
int minn=1e9;
for(int i=1;i<=n;i++)
{
cin>>x;
a[x]++;//统计数字个数
maxn=max(maxn,x);
minn=min(minn,x);//统计最大值,最小值,优化常数。
}
for(int i=minn;i<=maxn;i++)//从最小值到最大值
{
while(a[i]>0)//判断个数是否输出完
{
a[i]--;
cout<<i<<" ";
}
}
return 0;
}
计数排序显而易见有很大的漏洞:数最大值有多大,数组就得开多大
在我写这篇博客时,我旁边的lws说他在年轻的时候手写堆,来排序哈哈哈。
蒟蒻一名若有错漏请及时联系:)