算法回顾 排序

我太废了 感觉基本上是从头学起了QAQ以前的博客感觉也没啥用233333

为方便起见,以下排序后的数列均为递增数列。

1.插入排序 时间复杂度O(n^2)

基本思路:对于一串数列,从左到右扫描每一个元素,当前位置记为key。从key所在的位置倒着向前扫描,如果遇到有比key大的元素,就把这个数的位置向后移,直到找到第一个小于等于key的位置,然后把key加进去。(说的很抽象)

例如:2 1 5 3

从1开始倒着枚举,遇到2,此时2被存在a[1]中,于是让a[2]=a[1],继续往前枚举,发现扫到头了(i==0),/*也可以预先把a[0]设置成负无穷*/,再把key插进数列中。

数列变成了:1 2 5 3

从5开始倒着枚举,遇到2之后发现2比5小,可以直接break掉;(这种做法可以保证key位置前的数一定是有序的)

接着是3,遇到5 把5向后挪,遇到2,break,把3插进去(插的位置就是5往后挪之后空出来的位置)

发现所有位置都已经枚举完了,整个数列已经有序了。

    int j=2;cnt=0;
    while(j<=n){
        int key=a[j],i=j-1;
        for(i=j-1;i>=1;--i){
            if(a[i]>key) a[i+1]=a[i];
            else break;
        }
        a[i+1]=key;++j;
    }
View Code

 

2.冒泡排序(每个oier都会学到的经典23333)

可以解决逆序对相关问题。

大致思路:从第一个元素开始往后枚举,如果它比后面一个数大,就和后面一个数交换,直至当前数列中最大的数在数列末端(已经排好的默认被T出数列2333)。

例如:3 2 5 1

3比2大 swap 2 3 5 1;3小于5 不动 继续看后面一对 5比1大 swap 2 3 1 5;指针(不是严格意义上的)在第4位

接着又从头开始 2比3小 不动;3比1大 swap 2 1 3 5;指针在第三位

从头开始 2比1大 swap 1 2 3 5 指针在第2位;

时间复杂度:O(n^2)

View Code

 

3.快速排序(虽然我觉得这个代码可能写的机会很少)

快排的想法真的太妙了。

大致思路:设置一个基准值key(一般用开头元素),数列的一头一尾分别用i,j指示,然后从后开始搜索,找到第一个小于该元素的位置,将这两个元素交换(也可以直接用赋值操作);

接着从i+1开始遍历(i的位置刚才进行过交换,一定比基准值小,不予考虑),找到第一个小于基准值的位置,与a[j]交换//把这个数换到后面去;

一直反复进行这个操作 直至i==j(如果进行赋值操作,记得把基准值还回去)

此时 所有比基准值小的数都在i左侧,大的数都在i右侧,对两边分别进行递归操作排序。

很多博客 百度也写的很详细。(这个代码真的很少用到。。。。。)

void Sort(int bg,int ed){
    if(bg>=ed) return ;
    int i=bg,j=ed,key=a[i];//no a[i] directly for a[i] is changing
    while(i<j){
        while(a[j]>=key&&j>i) --j;if(j>i) swap(a[i],a[j]);//a[i++]=a[j];
        while(a[i]<=key&&i<j) ++i;if(i<j) swap(a[i],a[j]);//a[j--]=a[i];
    }
    //a[i]=key;//最后一定是i==j 
    Sort(bg,i);Sort(i+1,ed);
}
View Code

 

4.桶排序

我居然忘了这个 我爱桶排!!!!

桶排除了适用范围很小以外简直完美23333

codevs 明明的随机数

    scanf("%d",&n);
    for(int i=1;i<=n;++i) a[i]=0;
    for(int i=1;i<=n;++i){
        int x=1;scanf("%d",&x);++a[x];
    }
    int cnt=0;
    for(int i=1;i<=1000;++i) cnt+=(a[i]!=0);
    printf("%d\n",cnt);
    for(int i=1;i<=1000;++i) if(a[i]!=0) printf("%d ",i);
View Code

 

5.归并排序

Top Down

void update(int l,int r){
    int mid=l+r>>1,i=l,j=mid+1; 
    for(int k=l;k<=r;++k){
        if((i<=mid&&a[i]<a[j])||(j==r+1)) b[k]=a[i],++i;
        else b[k]=a[j],++j;
    }
    for(int i=l;i<=r;++i) a[i]=b[i];
}

void merge_sort(int begin,int end){
    if(end-begin<=0) return ;
    int mid=begin+end>>1;
    merge_sort(begin,mid);merge_sort(mid+1,end);
    update(begin,end); 
}
View Code

Bottom Up

void merge_sort2(){
    int len=1;
    while(1){
        len=len*2;
        for(int l=0;l<n;l+=len){
            int r=min(l+len-1,n-1),mid=min(l+(len>>1)-1,n-1);
            int i=l,j=mid+1;
            for(int k=l;k<=r;++k){
                if((j==r+1)||(i<=mid&&a[i]<a[j])) b[k]=a[i],++i;
                else b[k]=a[j],++j;
            }
            for(int k=l;k<=r;++k) a[k]=b[k];
        }
        if(len>=n) break;
    }
}
View Code

 

posted @ 2019-09-15 16:42  YWQQwQ  阅读(127)  评论(0)    收藏  举报