前言
排序算法在题目中经常需要用到,在程序中,我们一般打的是快排,归并,堆排等高效率排序,更有甚者会直接用sort排序,而今天,我要介绍一种奇特的排序方法——Monkey King 排序,我相信接下来的内容会对你有一定帮助。
算法简介
Monkey King 排序也称吉吉国王排序,是一种高效率 排序算法,其发明者是L.E.M.T蒟蒻,于2021年1月28日在机房划水时发明(其实是听取了他人的瞎搞口胡再加以优化),本算法学习门槛极低,适于初学者学习。
思想
模拟猴子(bushi)
我们设想取两个变量 x x x 和 y y y ,表示我们可能要交换的两个数, s w a p ( a [ x ] , a [ y ] ) swap(a[x],a[y]) swap(a[x],a[y]),交换之后 O ( n ) O(n) O(n)扫一遍判断当前序列是否合法即可。
这时可能有人会问:那时间复杂度不会很高吗?
确实!
所以下面便是吉吉国王排序的核心部分了!
也是降低时间复杂度的关键部分!
我们可以试想如何减少枚举 x x x y y y 的时间。不难想到我们可以模仿猴子随机选择两个数直接用这两个数交换。(yi本正经)
CODE如下
//This is monkeykingsort ! ! !
#include<bits/stdc++.h>
using namespace std;
int n,a[1000005],bj;
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=2;i<=n;i++) if (a[i]<a[i-1]) {
bj=1; break;}
srand(time(NULL));
while (bj) {
int x=rand()%n+1,y=rand()%n+1;
swap(a[x],a[y]),bj=0;
for (int i=2;i<=n;i++) if (a[i]<a[i-1]) {
bj=1; break;}
}
for (int i=1;i<=n;i++) printf("%d\n",a[i]);
}
但是如果脸黑怎么办呢???
那么很可惜,你不是真正的吉吉国王,但是我们可以通过优化把你变成真正的吉吉国王(???)
优化
当我们枚举两个数时,我们可以想一下什么情况下我们才可以交换。
很显然,当 x < y x<y x<y 且 a [ x ] > a [ y ] a[x]>a[y] a[x]>a[y] 的情况我们才能交换(从小到大排)
所以优化后的代码如下:
//This is monkeykingsort ! ! !
#include<bits/stdc++.h>
using namespace std;
int n,a[1000005],bj;
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=2;i<=n;i++) if (a[i]<a[i-1]) {
bj=1; break;}
srand(time(NULL));
while (bj) {
int x=rand()%n+1,y=rand()%n+1;
if (x>y) swap(x,y);
if (a[x]>a[y]) {
swap(a[x],a[y]),bj=0;
for (int i=2;i<=n;i++) if (a[i]<a[i-1]) {
bj=1; break;}
}
}
for (int i=1;i<=n;i++) printf("%d\n",a[i]);
}
我觉得还行~~~
时间复杂度
理论 O ( T N ) O(TN) O(TN)(T是交换次数,是“常数”,可以省去) 前提是脸足够好???
所以会退化到 O ( 无 限 ) O(无限) O(无限)???
就这样吧。。。