有趣的排序算法——Monkey King排序 详细介绍

前言

排序算法在题目中经常需要用到,在程序中,我们一般打的是快排,归并,堆排等高效率排序,更有甚者会直接用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]);
}

但是如果脸黑怎么办呢???
那么很可惜,你不是真正的吉吉国王,但是我们可以通过优化把你变成真正的吉吉国王(???)

优化

当我们枚举两个数时,我们可以想一下什么情况下我们才可以交换。

扫描二维码关注公众号,回复: 12395429 查看本文章

很显然,当 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()???

就这样吧。。。

不会真的有人看到这里吧(逃

猜你喜欢

转载自blog.csdn.net/qq_49972640/article/details/113358910
今日推荐