前言:

近来在学习STL标准库,做一份笔记并整理好,方便自己梳理知识、以后查找,也方便他人学习,两全其美,快哉快哉!

这里我会以中国大学慕课上北京大学郭炜老师的《程序设计与算法(一)C语言程序设计》中的十二章十三章为学习资料来做笔记。并且我会附上代码(只要我不偷懒的话)。若有没学习到的部分,我会继续找资料来更新学习笔记。

STL(Standard Template Library,标准模板库)

包含一些常用的算法如排序查找,和常用的数据结构如:可变长数组,链表,字典等。

优点:使用方便,(运行)效率较高。

注意:若要使用其中的算法,需要#include<algorithm>

一、排序(sort)

本质上是用快速排序算法实现。

用法1:对基本类型的数组(int,double,char...)从小到大排序

sort(数组名+n1, 数组名+n2);

n1和n2都是int类型表达式,可以包含变量

如果n1=0,则+n1可以不写

作用是将数组中下标范围为[n1,n2)的元素从小到大排序,下标为n2的元素不在排序区间内。

样例:

 1 int main(int argc, char const *argv[])
2 {
3     int a[] = {15,4,3,8,7,2,6};
4     sort(a,a+7);//对整个数组从小到大排序
5     for (int i = 0; i < 7; i++)
6     {
7         cout<<a[i]<<' ';
8     }//结果:2 3 4 6 7 8 15
9     cout<<endl;
10     int b[] = {15,4,3,8,7,2,6};
11     sort(b,b+3);
12     for (int i = 0; i < 7; i++)
13     {
14         cout<<b[i]<<' ';
15     }//结果:3 4 15 8 7 2 6
16     cout<<endl;
17     int c[] = {15,4,3,8,7,2,6};
18     sort(c+2,c+5);
19     for (int i = 0; i < 7; i++)
20     {
21         cout<<c[i]<<' ';
22     }//结果:15 4 3 7 8 2 6
23     cout<<endl;
24     return 0;
25 }

用法1

用法2:对元素类型为T的基本类型数组从大到小排序:

sort(数组名+n1,数组名+n2,greater<T>);

样例:

 1 int main(int argc, char const *argv[])
2 {
3     int a[] = {15,4,3,8,7,2,6};
4     int i;
5     sort(a,a+7,greater<int>());
6     for ( i = 0; i < 7; i++)
7     {
8         cout<<a[i]<<' ';
9     }//结果:15 8 7 6 4 3 2
10    
11     return 0;
12 }

用法2

用法3:用自定义的排序规则,对任何类型T的数组排序

使用这种用法的原因:在我们自己定义了一些类/结构体的时候,自带的排序规则可能无法使用,或者说我们需要用我们自己的方法来排序,这个时候我们就要自定义排序规则了。

sort(数组名+n1,数组名+n2,排序规则结构名());

排序规则结构的定义方式:

1 struct 结构名
2 {
3     bool operator()(const T & a1,const T & a2)const
4     {
5         //若a1应该在a2前面,则返回true
6         //否则返回false
7     }
8 };

定义方式

在bool operator()(const T & a1,const T & a2)const这一句中,要记得写上const,否则可能会有奇奇怪怪的错误。

样例1(自定义规则排序):

 1 struct rule1//从大到小排序
2 {
3     bool operator()(const int & a1,const int & a2)const
4     {
5         return a1 > a2;
6     }
7 };
8 struct rule2//按个位数从大到小排序
9 {
10     bool operator()(const int & a1,const int & a2)const
11     {
12         return a1%10 < a2%10;
13     }
14 };
15 void Print(int a[],int size)
16 {
17     for (int i = 0; i < size; i++)
18     {
19         cout<<a[i]<<",";
20     }
21     cout<<endl;
22 }
23 int main(int argc, char const *argv[])
24 {
25     int a[] = {12,45,3,98,21,7};
26     sort(a,a+sizeof(a)/sizeof(int));//从小到大排序
27     cout<<"1)";Print(a,sizeof(a)/sizeof(int));
28     //结果:1)3,7,12,21,45,98,
29     sort(a,a+sizeof(a)/sizeof(int),rule1());//从大到小排序
30     cout<<"2)";Print(a,sizeof(a)/sizeof(int));
31     //结果:2)98,45,21,12,7,3,
32     sort(a,a+sizeof(a)/sizeof(int),rule2());//按个位数从小到大排序
33     cout<<"3)";Print(a,sizeof(a)/sizeof(int));
34     //结果:3)21,12,3,45,7,98,
35     return 0;
36 }

用法3样例1(自定义规则排序)

样例2(结构体数组排序):

 1 struct Student
2 {
3     char name[20];
4     int id;
5     double gpa;
6 };
7 Student students [] =
8 {
9     {"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9},
10     {"Ala",333,3.5},{"Zero",101,4.0}
11 };
12 //排序范围是[n1,n2)的元素
13 //在使用二分查找时,查找规则必须和排序规则一致
14 struct StudentRule1//按姓名从小到大排
15 {
16     bool operator()(const Student & s1,const Student & s2)const{
17         if (stricmp(s1.name,s2.name) < 0)
18         {
19             return true;
20         }
21         return false;
22     }
23 };
24 struct StudentRule2//按id从小到大排
25 {
26     bool operator()(const Student & s1,const Student & s2)const{
27         return s1.id < s2.id;
28     }
29 };
30 struct StudentRule3//按gpa从高到低排
31 {
32     bool operator()(const Student & s1,const Student & s2)const{
33         return s1.gpa > s2.gpa;
34     }
35 };
36 void PrintStudents(Student s[],int size)
37 {
38     for (int i = 0; i < size; i++)
39     {
40         cout<<"("<<s[i].name<<","<<s[i].id<<","<<s[i].gpa<<")";
41     }
42     cout<<endl;
43 }
44 int main()
45 {
46     int n = sizeof(students)/sizeof(Student);
47
48     sort(students,students+n,StudentRule1());
49     PrintStudents(students,n);
50     //结果:(Ala,333,3.5)(Jack,112,3.4)(Mary,102,3.8)(Mary,117,3.9)(Zero,101,4)
51     sort(students,students+n,StudentRule2());
52     PrintStudents(students,n);
53     //结果:(Zero,101,4)(Mary,102,3.8)(Jack,112,3.4)(Mary,117,3.9)(Ala,333,3.5)
54     sort(students,students+n,StudentRule3());
55     PrintStudents(students,n);
56     //结果:(Zero,101,4)(Mary,117,3.9)(Mary,102,3.8)(Ala,333,3.5)(Jack,112,3.4)
57     return 0;
58 }

用法3样例2(结构体数组排序)

这些就是这次笔记的内容了,感谢大家读到这里,祝大家学习愉快,头发常驻!

C++STL标准库学习笔记(一)sort的更多相关文章

  1. C++STL标准库学习笔记(三)multiset

    C++STL标准库学习笔记(三)multiset STL中的平衡二叉树数据结构 前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标 ...

  2. C++STL标准库学习笔记(二)二分查找

    二.STL中的二分查找算法 1.binary_search 2.lower_bound 3.upper_bound 记得#include<algorithm>! 前言: 在这个笔记中,我把 ...

  3. C++STL标准库学习笔记(五)set

    前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来,这一篇后面主要都是我的记录了,为了防止大片蓝色字体出现,后面就不改蓝色 ...

  4. C++STL标准库学习笔记(四)multiset续

    自定义排序规则的multiset用法 前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来,只不过这一次的笔记主要是我的补充 ...

  5. python标准库学习-SimpleHTTPServer

    这是一个专题 记录学习python标准库的笔记及心得 简单http服务 SimpleHTTPServer 使用 python -m SimpleHTTPServer 默认启动8000端口 源码: &q ...

  6. STL标准库-算法-常用算法

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 介绍11种STL标准库的算法,从这11种算法中总结一下算法的基本使用 1.accumulate() 累加 2.for_each( ...

  7. STL标准库-容器-vector

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. 向量容器vector是一个动态数组,内存连续,它是动态分配内存,且每次扩张的原来的二倍. 他的结构如下 一 定义 vector ...

  8. numpy, matplotlib库学习笔记

    Numpy库学习笔记: 1.array()   创建数组或者转化数组 例如,把列表转化为数组 >>>Np.array([1,2,3,4,5]) Array([1,2,3,4,5]) ...

  9. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

随机推荐

  1. Django笔记&教程 5-2 进阶查询——Queryset

    Django 自学笔记兼学习教程第5章第2节--进阶查询--Queryset 点击查看教程总目录 Queryset相关内容其实蛮多的,本文只介绍一些常用的,详细的推荐查询官方文档:queryset-a ...

  2. Python-Unittest多线程执行用例

    前言 假设执行一条脚本(.py)用例一分钟,那么100个脚本需要100分钟,当你的用例达到一千条时需要1000分钟,也就是16个多小时... 那么如何并行运行多个.py的脚本,节省时间呢?这就用到多线 ...

  3. filter筛选数组

    和map()类似,array的filter也接收一个函数 和map()不同的是,filter把传入的函数依次作用于每个函数,然后根据返回TRUE还是FALSE来做决定保留还是舍弃该元素 例如,删除一个 ...

  4. python实现超大图像的二值化方法

    一,分块处理超大图像的二值化问题   (1) 全局阈值处理  (2) 局部阈值 二,空白区域过滤 三,先缩放进行二值化,然后还原大小 np.mean() 返回数组元素的平均值 np.std() 返回数 ...

  5. Linux检测磁盘空间

    在linux中,文件系统将所有的磁盘都并入一个虚拟目录下,在使用新的存储媒体之前,需要把它放到虚拟目录下,这项工作称为挂载. 1.mount命令 mount会输出当前系统上挂载的设备列表,要在虚拟目录 ...

  6. pm2 重启策略(restart strategies)

    使用 PM2 启动应用程序 时,应用程序会在自动退出.事件循环为空 (node.js) 或应用程序崩溃时自动重新启动. 但您也可以配置额外的重启策略,例如: 使用定时任务重新启动应用程序 文件更改后重 ...

  7. Dockerfile之CMD与Entrypoint使用要点

    CMD与ENTRYPOINT都可以代表容器的启动命令,单丛语义上来理解,CMD是一个命令或者口令,而ENTRYPOINT则是一个入口(相当于容器启动时的入口),那么其实就可以理解为每当我们开启一个容器 ...

  8. Codeforces 986E - Prince's Problem(树上前缀和)

    题面传送门 题意: 有一棵 \(n\) 个节点的树,点上有点权 \(a_i\),\(q\) 组询问,每次询问给出 \(u,v,w\),要求: \(\prod\limits_{x\in P(u,v)}\ ...

  9. fping (比ping更强大的ping工具)

    Fping程序类似于ping(ping是通过ICMP(网络控制信息协议InternetControl Message Protocol)协议回复请求以检测主机是否存在).Fping与ping不同的地方 ...

  10. 网站性能调优实战-学相伴KuangStudy

    面对并发我们是如何优化KuangStudy网站性能的? 每个项目都会随着用户和数据的增长调整架构,来面对未来的问题,我们也不例外,在1月5号我们平台正式公测后,引起了很多观众的热烈反响,仅仅4天,注册 ...