模板:排序(一)

在续讲故事之前,我们先来聊一聊勇者打工的经历。
*
停,在那之前还得科普一件事情。我们来讲一下什么是排序算法的稳定性。
这个大概是最玄学的东西了,引用百科的话:
“假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。”
好的定义弄明白了,我们也大概知道不稳定有什么坏处了——就是如果有相同的数字的话,不稳定的算法就会将他们再排一遍,从而浪费时间。
然后呢,再补上一句百科的话,咱们开始讲正文:
“需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。”
*

话说勇者在keke的工厂里干活,keke的工厂主要是负责工业(而且这个世界上只有这一个工厂),所以来找他要钢材的人特别多。Keke按照订单顺序已经生产出了不同长短的钢材,但是为了派货方便,他决定将钢材按照从大到小的顺序排列。
“什么鬼啊怎么keke要解决问题就来找我呢?”勇者抱怨道。
“听说解决问题的人可以获得一个int的Gold……”路由器小声说。
“那还等什么啊快去干啊!”
然而keke的厂子很多,每一个厂子的特性不一样。
——————————

选择排序

(瞎编题时间)
Keke的第一个厂子没什么特别的,客人都是拖延症,不着急来拿钢材,所以随便搞,只要将钢材从大到小排列就好了。
——————————
勇者虽然一根筋,但是最基础的想法还是有的“只要枚举每次没排序区间内的最大值将它放在前面不就好了?”
于是,他很快的写好了一段魔法代码,经路由器认定,这就是选择排序。而且由于用到了两层循环,故复杂度为O(N*N)

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int INF=-99999999;
int main(){
    int n,a[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int maxn=INF,num=0,sum=1;
    while(sum!=n){
        for(int i=sum;i<=n;i++){
            if(maxn<a[i]){
                maxn=a[i];
                num=i;
            }
        }
        int t=a[num];a[num]=a[sum];a[sum]=t;sum++;maxn=INF; 
    }
    for(int i=1;i<=n;i++){
        printf("%d ",a[i]);
    }
    return 0;
}

*是的这里路由器再插一嘴。
从前也误导过其他童鞋,因为我曾经在最开始学排序的时候写过这样的代码*

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int main(){
    int n,a[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(a[i]>a[j]){
                int temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
    }
    for(int i=1;i<=n;i++){
        printf("%d ",a[i]);
    }
    return 0;
}

*
我一直以为是冒泡排序…………特别尴尬,所以在此纠正我写的其实是很low的选择排序哦!(但是说实话,这代码好背啊,而且如果换排序的话一般都会用快排的说很少用到o(n*n)的算法……)”
*

冒泡排序

原代码

但是勇者得意的时候,路由器却说“我查了一下,这个魔法貌似不稳定啊……”
勇者火冒三丈“啊?但是你看一下定义啊!它哪里不稳定了?”
确实啊,两个魔法程序丝毫不违背定义,因此路由器经过深思熟虑之后,自我认为他们应该是稳定的。其实网上关于选择排序到底是不是稳定的已经争论很久了,在此路由器给出的看法是:看代码实现是怎样的,他的稳定性就是怎样的。
“那既然有人说不稳定的话,你不如再写一个……”路由器小声嘟囔道。
“好啊!有人挑战我不是吗,我再写一个!”
于是,勇者花了一天一夜的时间,又写了一个魔法,经过路由器认定,这个是冒泡排序O(N*N)也是显而易见的。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int main(){
    int n,a[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    bool ok=1; 
    for(int i=1;i<=n-1;i++){
        for(int j=1;j<=n-1;j++){
            if(a[j]<a[j+1]){
                int t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
                ok=0;
            }
        }
        if(ok==1)break;
    }
    for(int i=1;i<=n;i++){
        printf("%d ",a[i]);
    }
    return 0;
}

勇者自豪地说:“这个就是将两个相邻的数字进行比较,将大的往上浮,小的往下沉,这样一遍一遍来,总是能将所有大的放在上面,小的沉在下面。”
“而且,这个魔法最高明之处(勇者又有点嘚瑟了),在于在已经排好序的情况下,用ok判断是否已经排好序了,如果我们跑一趟却发现没有发生一次交换的话,那就说明已经排好序了,因此直接跳出循环就可。”
“诶嘿,想不到你还蛮聪明的吗?不过我这里还有一个更好的优化”路由器神秘一笑,在某个魔法书里找到了:

鸡尾酒排序——冒泡排序的改进

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int main(){
    int n,a[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int top=1,bot=n;
    bool ok=1;
    while(top<=bot){
        ok=1;
        for(int j=top;j<=bot-1;j++){
            if(a[j]<a[j+1]){
                int t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
                ok=0;
            }
        }
        if(ok==1)break; 
        for(int j=bot-1;j>=top;j--){
            if(a[j+1]>a[j]){
                int t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
                ok=0;
            }
        }
        if(ok==1)break; 
        top++;bot--; 
    }
    for(int i=1;i<=n;i++){
        printf("%d ",a[i]);
    }
    return 0;
}

“这个之所以好,就在于它从后往前扫了一遍,从前往后又扫了一遍,等于双向冒泡,对于像类似于3 2 1 4这类的数据有奇效哦。”
勇者高兴地将冒泡排序魔法交给了第一个厂子,开赴下一个厂子。
————————————
但是故事还没有结束。勇者到底能不能拿到int个G呢?敬请期待下一篇……

 

posted @ 2017-05-05 21:17  luyouqi233  阅读(181)  评论(0编辑  收藏  举报