常用排序算法

 如题:第一行输入一个数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~~

 

posted @ 2016-08-18 09:58  多一份不为什么的坚持  阅读(331)  评论(0编辑  收藏  举报