选择排序
为什么叫选择,因为每次都选出来两个大冤种进行交换
这样复杂度就成为了优秀的
O
(
n
2
)
O(n^2)
O(n2)
void selection_sort(int a[],int n){
for(int i=1;i<n;++i){
int tmp=i;
for(int j=i+1;j<=n;++j){
if(a[j]<a[tmp]) tmp=j;
}
swap(a[tmp],a[i]);
}
}
非常之easy,因为涉及swap这个操作,这个排序不稳定
冒泡排序
这个就有点东西了昂(只是指名字):在这个算法执行的过程中,较小的元素会像是气泡慢慢地浮出水面
它每一轮比较相当于把最大的元素往后面送,所以我们只要需要执行
(
n
−
1
)
+
(
n
−
2
)
+
.
.
.
+
1
=
(
n
−
1
)
n
2
(n-1)+(n-2)+...+1=\frac{(n-1)n}{2}
(n−1)+(n−2)+...+1=2(n−1)n
所以复杂度就是
O
(
n
2
)
O(n^2)
O(n2) 而且它是稳定的
void Bubble_sort(int a[], int n) {
for (int i = 1; i < n; i ++) {
int cnt = 0;
for (int j = 1; j <= n-i; j++) {
if (a[j] > a[j+1]) {
a[j]=a[j]^a[j+1],a[j+1]=a[j]^a[j+1],a[j]=a[j]^a[j+1];
cnt=1;
}
}
if (!cnt) break;
}
}
冒泡是稳定的e
插入排序
这个排序但凡有点生活经历的人都会,因为你打扑克(假设只有你一个人摸牌)的时候就是从待排的扑克堆里拿出一张,然后在从你手里的牌中找个合适的位置插入,复杂度
O
(
n
2
)
O(n^2)
O(n2)
插入排序是稳定的昂
void insert_sort(int a[],int n){
for(int i=1;i<n;++i){
int tmp=a[i],j=i-1;
while(j>=0&&a[j]>tmp){
a[j+1]=a[j];
j--;
}
a[j+1]=tmp;//上边的while循环你把a[j]挪到a[j+1],准备把手里的牌放到a[j]但是又j-- ,所以是这样写
}
} //我这个写法非常的帅气昂 这a[i]就是你摸出来的牌 a[j]就是你手里牌的最后一张 因为i前面都排好序了(这就是插入排序的结果)
//然后每次比较 举个例子 259 你排三 最后成为这样 2559 然后再变成 2359 相当于把比你大的都往后移一格
基数排序
这个排序算法的核心就在于每次按照个、十……的顺序排序(只能按照这个顺序,因为如果按照最高位排序的话后面会出问题的),它的时间复杂度取决于你所选择的k
:
:
:
O
(
log
k
m
a
x
x
∗
(
n
+
k
)
)
O(\log_{k}{maxx} *(n+k))
O(logkmaxx∗(n+k)) 前面的通常可以看成是常数不考虑**
基数排序是稳定的昂
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,k,val[N],cnt[N],tmp[N],m;
void init(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i) scanf("%d",&val[i]);
int maxx=val[1];m=1;
for(int i=2 ;i<=n;++i) maxx=max(maxx,val[i]);
while(maxx>=k){
maxx/=k;
m++;
}
}
void radix_sort (){
int base=1;
for(int i=1;i<=m;i++){
memset(cnt,0,sizeof cnt);
for(int j=1;j<=n;++j) cnt[val[j]/base%k]++;
for(int j=1;j<=k;++j) cnt[j]+=cnt[j-1];
for(int j=n;j;j--){
tmp[cnt[val[j]/base%k]]=val[j];
cnt[val[j]/base%k]--;
}
for(int j=1;j<=n;++j) val[j]=tmp[j];
base*=k;
}
}
int main(){
init();
solve();
for(int i=1;i<=n;++i) printf("%d ",val[i]);
return 0;
}
桶排序
就是跟分块一样,按值域分成若干个桶,然后进行排序(桶内插排,因为范围小)
因为这份代码基于插排,所以是稳定的
const int N = 100010;
int n, w, a[N];//w为值域最大值
vector<int> bucket[N];
void insertion_sort(vector<int>& A) {
for (int i = 1; i < A.size(); ++i) {
int key = A[i],j = i - 1;
while (j >= 0 && A[j] > key) {
A[j + 1] = A[j];
--j;
}
A[j + 1] = key;
}
}
void bucket_sort() {
int bucket_size = w / n + 1,p=0;
for (int i = 0; i < n; ++i) bucket[i].clear();
for (int i = 1; i <= n; ++i) bucket[a[i] / bucket_size].push_back(a[i]);
for (int i = 0; i < n; ++i) {
insertion_sort(bucket[i]);
for (int j = 0; j < bucket[i].size(); ++j) {
a[++p] = bucket[i][j];
}
}
}
归并排序
#include <bits/stdc++.h>
using namespace std;
const int N=105;
int n,a[N],tmp[N];
void merge_sort(int a[],int l,int r){
if(l>=r) return;
int mid=l+r>>1;
merge_sort(a,l,mid),merge_sort(a,mid+1,r);
int k=1,i=l,j=mid+1;
while(i<=mid&&j<=r)
if(a[i]<=a[j]) tmp[k++]=a[i++];
else tmp[k++]=a[j++];
while(i<=mid) tmp[k++]=a[i++];
while(j<=r) tmp[k++]=a[j++];
for(int i=l,j=1;i<=r;++i,j++) a[i]=tmp[j];
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
merge_sort(a,1,n);
for(int i=1;i<=n;++i) printf("%d ",a[i]);
return 0;
}