算法笔记—入门篇(2)—算法初步(更新中......)

前情回顾-冒泡排序(语言篇)

冒泡排序是排序中最基本的一种方法,虽然在写题时我们一般不会去使用它,但我觉得了解冒泡排序算法的实现原理确实非常必要的。

冒泡排序的本质在于交换,即每次通过交换的方式把当前剩余元素的最大值移动到一端,当剩余元素为0时,排序结束。

1.简单选择排序

① 数组A中元素A[1]~A[N],

② 令 i 从 1 到 n 进行 n 趟操作,每趟操作从A[i]~A[N]中选出一个最小的元素,

③ 令其与待排序部分的第一个元素A[i]交换,最后所有元素有序。

#include<stdio.h>
int main(){
    int a[100];
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    int min=9999;
    for(int i=0;i<n;i++){
        int mi;
        for(int j=i;j<n;j++){
            if(a[j]<min){
                min=a[j];
                mi=j;
            }
        }
        int temp=a[i];
        a[i]=a[mi];
        a[mi]=temp;
    }
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
    return 0;
}

2.直接插入排序

前一部分为有序数列,后一部分为无序数列,

把无序部分的第一个元素放入有序部分,找到合适的位置,

这个过程中有序部分可能需要进行后移操作,直至操作n-1趟。

#include<stdio.h>
int main(){
    int n;
    int a[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=2;i<=n;i++){
        int temp=a[i],j=i;
        while(j>1&&temp<a[j-1]){
            a[j]=a[j-1];
            j--;
        }
        a[j]=temp;
    }
    for(int i=1;i<=n;i++){
        printf("%d ",a[i]);
    }
    return 0;
}

3.sort排序(排序神器)

sort()函数是C++中用于排序的一个函数,比较高效。

如何使用sort排序:

①需加头文件#include<algorithm>和using namespace std;

②sort(首元素地址,尾元素的下一个地址,比较函数(可选))

sort函数的参数有三个,其中前两个是必填的,比较函数可以根据需要填写。

#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
    int a[6]={9,4,2,5,6,-1};
    sort(a,a+4);//将a[0]-a[3]从小到大排序
    for(int i=0;i<4;i++){
        printf("%d ",a[i]);
    }
    printf("
");
    sort(a,a+6);
    for(int i=0;i<6;i++){
        printf("%d ",a[i]);
    }
    return 0; 
} 

如何实现比较函数cmp:

sort函数默认是将数组进行从小到大的排序,如果想要从大到小排序,则需要使用比较函数cmp来实现。

#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int a[6]={9,4,2,5,6,-1};
    sort(a,a+4,cmp);//将a[0]-a[3]从大到小排序
    for(int i=0;i<4;i++){
        printf("%d ",a[i]);
    }
    printf("
");
    sort(a,a+6,cmp);
    for(int i=0;i<6;i++){
        printf("%d ",a[i]);
    }
    return 0; 
} 

结构体数组的排序:

可以按照结构体内的元素的大小进行排序

#include<stdio.h>
#include<algorithm>
using namespace std;
struct node{
    int x,y;
}ssd[10]; 
bool cmp(node a,node b){
    return a.x>b.x;//按照x从大到小排序 
}
int main(){
    ssd[0].x=2;
    ssd[0].y=2;
    ssd[1].x=1;
    ssd[1].y=3;
    ssd[2].x=3;
    ssd[2].y=1;
    sort(ssd,ssd+3,cmp);
    for(int i=0;i<3;i++){
        printf("%d %d
",ssd[i].x,ssd[i].y);
    } 
    return 0; 
} 

如果想先按x从大到小排序,如果x相等,则按y从小到大排序(二级排序),则cmp的写法为:

bool cmp(node a,node b){
    if(a.x!=b.x)
        return a.x>b.x;//按照x从大到小排序 
    else
        return a.y<b.y;
}

4.复杂的结构体排序:

自己尝试了几次,没有通过全部样例,id我原本采用long long 存储,无法通过,只能用字符串。

题目大意:

n个考场,每个考场m个学生,输入学生学号和成绩,进行考场内排序和总的排序。输出内容:学号,总名次,考场号,考场内名次

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct student{
    char id[15];
    int loc_num;
    int loc_rank;
    int score;
}stu[30010];
bool cmp(student a,student b){
    if(a.score!=b.score) return a.score>b.score;
    else return strcmp(a.id,b.id)<0;
} 
int main(){
    int n;//n为考场数 
    int m;//m为考场内人数
    int k=0;//k为考生总数 
    scanf("%d",&n); 
    for(int i=1;i<=n;i++){
        scanf("%d",&m);
        for(int j=0;j<m;j++){
            scanf("%s %d",stu[k].id,&stu[k].score);
            stu[k].loc_num=i;
            k++;
        }
        sort(stu+k-m,stu+k,cmp);
        stu[k-m].loc_rank=1;
        for(int j=k-m+1;j<k;j++){
            if(stu[j].score==stu[j-1].score){
                stu[j].loc_rank=stu[j-1].loc_rank;
            }else{
                stu[j].loc_rank=j+1-(k-m);
            }
        }
    }
    printf("%d
",k);
    sort(stu,stu+k,cmp);
    int r=1;
    for(int i=0;i<k;i++){
        if(i>0&&stu[i].score!=stu[i-1].score)
            r=i+1;
        printf("%s ",stu[i].id);
        printf("%d %d %d
",r,stu[i].loc_num,stu[i].loc_rank);    
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/nyist0/p/10216680.html