排序(sort),是C++中一种重要的算法,其中,最常用的就是这几种了:
方式 | 稳定性 | 时空复杂度 |
---|---|---|
冒泡排序 | 稳定 | O(n²) |
鸡尾酒排序 | 不太稳定 | O(nlogn) |
分治排序 | 不稳定 | O(logn) |
插入排序 | 稳定 | O(n^2) |
计数排序 | 超级稳定 | O(1) |
冒泡排序和鸡尾酒排序
冒泡排序(bubble sort)之前讲过,懒得说了,详见:
https://blog.csdn.net/shit54188/article/details/128408417?spm=1001.2014.3001.5501
而只因尾酒排序94将本来n次顺序给为n/2趟来回,10分简单
分治排序
也称归并排序,是分治算法的一种,把数组分为若干个无序区间,再进行排序,我这也不是很懂,看下TA的吧:
//Project - MergeSort
#include <cstdio>
#include <cstdlib>
void merge(int a[],int low, int mid, int high) {
int* t = (int*)malloc((high-low+1)*sizeof(int));
int i = low, j = mid+1, k = 0;
while (i<=mid && j<=high){
if (a[i]<=a[j])
t[k++] = a[i++];
else
t[k++] = a[j++];
}
while (i<=mid)
t[k++] = a[i++];
while (j<=high)
t[k++] = a[j++];
for (i=low,k=0;i<=high;i++,k++)
a[i] = t[k];
free(t);
}
void mergeSort(int a[], int low, int high) {
if (low<high){
int mid = (low+high)/2;
mergeSort(a,low,mid);
mergeSort(a,mid+1,high);
merge(a,low,mid,high);
}
}
int main() {
int v[8] = {8,4,2,9,5,3,1,7};
mergeSort(v,0,7);
printf("Sorted: ");
for (int i=0;i<8;i++)
printf("%d ",v[i]);
return 0;
}
插入排序
只要一直把无序区间中最大/最小 的数插入有序区间就行了
废话不说,上代码:
#include <bits/stdc++.h>
#define N 1550
using namespace std;
int a[N], n;
int main() {
// 输入
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i];
// 插入排序
for (int i = 2; i <= n; ++i) { // 按照第2个到第n个的顺序依次插入
int j, x = a[i]; // 先将i号元素用临时变量保存防止被修改。
// 插入过程,目的是空出分界线位置j,使得所有<j的部分<=x,所有>j的部分>x。
// 循环维持条件,j>1,并且j前面的元素>x。
for (j = i; j > 1 && a[j - 1] > x; --j) {
// 满足循环条件,相当于分界线应向前移,
// 分界线向前移,就等于将分界线前面>x的元素向后移
a[j] = a[j - 1];
}
// 找到分界线位置,插入待插入元素x
a[j] = x;
}
// 输出
for (int i = 1; i <= n; ++i) cout << a[i] << ' ';
cout << endl;
return 0;
}
计数排序
这是一个堪称史上最low最简单最强最稳定的排序,计算出a数组各个数出现次数,之后存放在b[Max]里,在按个数输出
#include <bits/stdc++.h>
using namespace std;
int a[1000005],n, b[1000005],cnt[1000005];
int main() {
cin >> n;
for (int i=1;i<=n;++i) {
cin >> a[i];
++cnt[a[i]];
}
for (int i=0,j=0;i<1000005;++i){
for (int k=1;k<=cnt[i];++k){
b[++j]=i;
}
}
for (int i=1;i<=n;++i){
cout<<b[i]<<' ';
}
return 0;
}
不难看出时空复杂度为O(1),就问你强不强?