对结构体元素进行排序

15 篇文章 0 订阅

知识点一:sort()

sort()函数的头文件是algorithm,又被称为快速排序。其使用形式为:

  • sort(start_address, end_address, [rule])

我们在使用简单的对数组元素或是字符串排序的时候,第三个参数往往是省略的,代表你的排序规则默认是从小到大排序,当然也可以带参数,那么就可以通过用系统的排序规则sort(a,a+7,less<int>();实现从小到大排序,或者是使用sort(a,a+7,greater<int>());用系统的排序规则,从大到小排序。

另外,sort中的地址是左闭右开的形式,所以需要明白排序元素的个数。

关于STL中的sort:很建议去参看另一篇大佬的博客:https://blog.csdn.net/Hanani_Jia/article/details/82498469,内容是更实在的东西,当然关于一些逻辑上的思路,简单的可以参看下面的一段内容:

STL的sort()算法,数据量大时采用Quick Sort,分段递归排序。一旦分段后的数据量小于某个阈值,为避免Quick Sort的递归调用带来过大的额外开销,就改用Insertion Sort(插入排序)。如果递归层次过深,还会改用Heap Sort。

STL中的sort并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序。

快速排序最关键的地方在于枢轴的选择,最坏的情况发生在分割时产生了一个空的区间,这样就完全没有达到分割的效果。STL采用的做法称为median-of-three,即取整个序列的首、尾、中央三个地方的元素,以其中值


原文:https://blog.csdn.net/vanturman/article/details/81706538 

知识点二:结构体排序

俗话说工欲善其事必先利其器,知道了sort的原理,我们就可以进行排序了,当然也可以自己设计排序规则,而且结构体可以直接进行赋值,也很方便。

如果想通过sort进行排序,那么就需要知道如何设计排序规则,假设我们有三个变量来描述一个学生,如果名字一样,就通过年龄排序,如果年龄也相同,就通过成绩来排序,默认的顺序都是从小到大的顺序进行排序。

于是首先设计结构体student:

struct student{
    string name;    //姓名
    int age;        //年龄
    int grade;      //成绩
};

第二个问题,也是难点,设计排序规则,那么就需要了解sort的实现原理。在自己的设计规则中,引用的两个串不希望改变它们的值所以设计为const引用,然后考虑具体的规则:默认排序是按照从小到大的顺序进行排序,所以如果两个对象的name不相等,那么就返回s1.name < s2.name ,这是对于name 不相等的情况,对于name相等,我们还需要考虑age相不相等,如果不考虑,默认是按照数组中的原本顺序排列的,不会做排序处理。

int comp(const student &s1,const student &s2){
    if(s1.name == s2.name && s1.age != s2.age){
        return s1.age < s2.age;
    }
    else if(s1.name == s2.name && s1.age == s2.age){
        return s1.grade < s2.grade;
    }
    else{
        return s1.name < s2.name;
    }
}

测试代码:

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

//按姓名从小到大排序,姓名一样,按年龄从小到大排序
struct student{
    string name;    //姓名
    int age;        //年龄
    int grade;      //成绩
};

//自己定义的排序规则
int comp(const student &s1,const student &s2){
    if(s1.name == s2.name && s1.age != s2.age){
        return s1.age < s2.age;
    }
    else if(s1.name == s2.name && s1.age == s2.age){
        return s1.grade < s2.grade;
    }
    else{
        return s1.name < s2.name;
    }
}

int main(){
    student s[100];
    s[0].name = "zhangsan"; s[0].age = 19; s[0].grade = 20;
    s[1].name = "zhangsan"; s[1].age = 18; s[1].grade = 20;
    s[2].name = "lisi";     s[2].age = 20; s[2].grade = 20;
    s[3].name = "zhangsan"; s[3].age = 19; s[3].grade = 2;
    s[4].name = "zhangsan"; s[4].age = 17; s[4].grade = 20;
    s[5].name = "lisi";     s[5].age = 20; s[5].grade = 15;
    sort(s, s + 6, comp);       //左闭右开,所以是对s[0]到s[6]排序

    for(int i = 0; i < 6; i++){
        cout<<s[i].name<<" "<<s[i].age<<" "<<s[i].grade<<endl;
    }

    return 0;
}

 

  • 16
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值