• 常用排序算法


     如题:第一行输入一个数n,为整数个数。第二行有n个数,每个数都不超过int类型。

     输出升序排序后的数,以空格隔开。

     1.冒泡排序

      两两比较,如果不满足条件则交换位置。

     1 #include <iostream>
     2 #include <cstdio>
     3 
     4 using namespace std;
     5 
     6 int a[100005];
     7 
     8 int main()
     9 {
    10     int n;
    11     scanf("%d",&n);
    12     for(int i=0;i<n;i++){
    13         scanf("%d",&a[i]);
    14     }
    15     for(int i=0;i<n-1;i++){
    16         for(int j=0;j<n-1-i;j++){
    17             if(a[j]>a[j+1]){
    18                 int temp=a[j];
    19                 a[j]=a[j+1];
    20                 a[j+1]=temp;
    21             }
    22         }
    23     }
    24     for(int i=0;i<n;i++){
    25         printf("%d ",a[i]);
    26     }
    27     return 0;
    28 }

    2.优化的冒泡排序

      第一步优化:如果里面一层循环在某次扫描中没有执行交换,则说明此时数组已经全部有序列,无需再扫描了。因此,增加一个标记,每次发生交换,就标记,如果某次循环完没有标记,则说明已经完成排序。

    void each(int *a,int *b){
        int temp=*a;
        *a=*b;
        *b=temp;
    }
    
    //第一步优化冒泡排序
    void bubble_sort(int a[],int n){
        bool b=false;
        for(int i=0;i<n-1&&b==false;i++){
            b=true;
            for(int j=n-1;j>i;j--){
                if(a[j-1]>a[j]){
                   each(&a[j-1],&a[j]);
                   b=false;
                }
            }
        }
    }

      第二步优化:在第一步的基础上思考,既然可以记录序列是否已经有序,那么当无序的时候,是否可以记录里面有序的部分呢。

      看第一步优化后的代码,每次内循环之前,前i项是有序的。当进行内循环时,如果最后一次进行交换的下标是lasttemp,那么不就说明从i到lasttemp都没有再进行交换,就说明i到lasttemp这一段也是有序的,那么前lasttemp说明也是有序的。下一次内循环之前,就不用再从n-1到i了,从n-1到lasttemp即可。

    void each(int *a,int *b){
        int temp=*a;
        *a=*b;
        *b=temp;
    }
    
    //第二步优化冒泡排序
    void bubble_sort(int a[],int n){
        int lasttemp;
        for(int i=0;i<n-1;i++){
            lasttemp=n-1;
            for(int j=n-1;j>i;j--){
                if(a[j-1]>a[j]){
                   each(&a[j-1],&a[j]);
                   lasttemp=j;
                }
            }
            i=lasttemp-1;//因为下一步是i++,所以先-1.
        }
    }

    3.选择排序

       每遍历一次找出最大的元素,放无序序列的最后一位。

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    int a[100005];
    
    int main()
    {
        int n;
        int maxx;//每次存储最大数的下标
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        
        //选择排序
        for(int i=n-1;i>=0;i--){
            maxx=0;
            for(int j=0;j<=i;j++){
                if(a[maxx]<a[j]){
                    maxx=j;
                }
            }
            int temp=a[maxx];
            a[maxx]=a[i];
            a[i]=temp;
        }
        
        for(int i=0;i<n;i++){
            printf("%d ",a[i]);
        }
        return 0;
    }

    4.插入排序

    void each(int *a,int *b){
        int temp=*a;
        *a=*b;
        *b=temp;
    }
    //插入排序
    void insertion_sort(int a[],int n){
        for(int i=1;i<n;i++){
            for(int j=i;j>=1;j--){
                if(a[j]<a[j-1]){
                    each(&a[j],&a[j-1]);
                    continue;
                }
                break;
            }
        }
    }

    5.改进的插入排序

      插入排序本来是一个一个地比较,然后找到最终的插入位置,但是这个查找位置过程可以用二分查找法代替,找到插入位置后,把它往后的元素全部往后平移一位,再将第i个数插入进去。当有100000个元素时,可以将比较次数减少到20以内。

    int a[100005];//全局数组
    
    int binarysearch(int en,int num){
        int st=0;
        if(num<=a[st]){
            return 0;
        }
        if(num>=a[en]){
            return en+1;
        }
        while(st+1!=en){
            int mid=(st+en)/2;
            if(num==a[mid]){
                return mid;
            }
            if(num<a[mid]){
                en=mid;
            }
            if(num>a[mid]){
                st=mid;
            }
        }
        return en;
    }
    
    //插入排序
    void insertion_sort(int n){
        for(int i=1;i<n;i++){
            int en=binarysearch(i-1,a[i]);
            if(en==i){
                continue;
            }else{
                int t=a[i];
                for(int j=i;j>en;j--){
                    a[j]=a[j-1];
                }
                a[en]=t;
            }
    
        }
    }

    持续更新ing~~

  • 相关阅读:
    Laravel 中查询 where 记录
    eclipse svn重定位(relocate)
    使用git ftp发布我个人的hexo博客内容
    oracle数据库查询常用语句
    telnet关闭tomcat
    XML字符串解析成对象的时候应注意空格
    去除焦点边框线
    如何查看和更改mysql数据库文件存放位置
    设置div,td失去焦点
    (加减乘除)字符串计算机
  • 原文地址:https://www.cnblogs.com/TWS-YIFEI/p/5782902.html
Copyright © 2020-2023  润新知