学习C/C++语言的基础很简单,但是写写算法的能力不是人人都具备的,本人蒟蒻一枚,时常感觉算法的概念原理都懂,但就是写不出来东西,于是发现了一个“百宝箱”——STL(Standard Template Library,标准模板库)
一般分为algorithm(算法)、container(容器)和iterator(迭代器)三类。模板库内容主要包含了一些常用的算法如快速排序、简单查找等,当然还包括了一些常用的数据结构,如可变长数组、链表、字典等。
一般以它的高效著称。注解:打比赛return 0少不了!!!
快速排序sort
sort排序是学习STL必须要知道的,内部算法结构是快速排序,不懂的同学可以先去了解一下快排的原理,毕竟手打快排也有可能在比赛场上需要。
#include
#include
#include
using namespace std;
int main(){
int a[10];
for(int i=0;i<10;i++){
a[i]=rand()%100;//存入十个随机数
}
for(int i=0;i<10;i++){
cout<
那么如何从大到小排序呢?
其实sort方法有内置好的方法让你从大到小排序,在这里,我们讲一下如何自己写一个方法从大到小排序。
#include
#include
#include
using namespace std;
bool cmp(int x,int y){//这里的参数一定要是你排序类型的参数
return x>y;//从大到小排序
}
int main(){
int a[10];
for(int i=0;i<10;i++){
a[i]=rand()%100;//存入十个随机数
}
for(int i=0;i<10;i++){
cout<
![在这里插入图片描述](https://img-blog.csdnimg.cn/202104090001127.png)
一般sort排序是针对字典序进行排序,所以当你是字符串数组的时候也是可以进行排序的,这一点大家可以自行尝试。同时还支持double类型的排序,也可以尝试一下。
针对结构体数据也可以使用sort进行排序,我们以输入学生成绩进行排序为例子,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面。
#include
#include
using namespace std;
int n;
struct stu{
int num;//学号
int c,m,e;//三科成绩
int sum;//总分
}student[310];//定义学生的结构体类型
bool cmp(stu a,stu b){
if(a.sum>b.sum){
return a.sum>b.sum;
}else if(a.sumb.c){
return a.c>b.c;
}else if(a.c> n;
for(int i=1;i<=n;i++){
student[i].num=i;
cin>>student[i].c>>student[i].m>>student[i].e;
student[i].sum=student[i].c+student[i].m+student[i].e;
}
sort(student+1,student+n+1,cmp);
for(int i=1;i<=5;i++)
cout<
vector 向量容器
vector 向量容器是一种简单高效的容器,在尾端插入和删除元素,算法时间为O(1),其他元素插入和删除时间为O(n)。vector可动态调整所占用的内存空间。
在此之前导入**#include**
vector,T代表类型,类似于你定义数组的类型一样。
也被称为动态数组,当你做题目的时候如果遇到数组空间大小不确定的情况下,可以考虑使用它,同样也很高效,首先要了解它常用的几种方法。
如何存数据?
#include
#include
using namespace std;
int main(){
vector < int > v ;
v.push_back(30); //此时是从尾端插入新元素
v.push_back(23);
v.push_back(11);
return 0;
}
如何取数据
采取数组的方式读取数据
#include
#include
using namespace std;
int main(){
vector < int > v ;
v.push_back(30); //此时是从尾端插入新元素
v.push_back(23);
v.push_back(11);
for(int i = 0 ; i < v.size() ; i++ ){
cout<
采取迭代器的方式读取数据
#include
#include
using namespace std;
int main(){
int j ;
vector < int > v ;
v.push_back (11) ; //尾插入新元素
v.push_back (23) ;
// v.clear () ; //清空全部元素
v.push_back (30) ;
v.push_back(1);
v.push_back(16);
v.insert ( v.begin() + 3 , 41 ) ; //插入41在第3个元素的后面
//一定要去动手验证一下结果
v.insert ( v.begin(), 15 ) ; //插入15为首元素
v.insert ( v.end(), 12 ) ; //插入12为末元素
v.erase ( v.begin() + 2) ; //删除第三个元素
v.erase ( v.begin() , v.begin() + 2 ) ; //删除前三个元素
//迭代器访问
vector < int > :: iterator i ;
for( i=v.begin(),j=0;i!=v.end();i++,j++ ){//从头到尾来进行扫描
cout<<"v["< :: reverse_iterator re ; //反向迭代器
for( re = v.rbegin() ; re != v.rend() ; re++ ){ //转置方法
cout<<*ri<
结构体容器
#include
#include
using namespace std;
struct stu{
int x;
int y;
};
int main()
{
int j ;
vector v1 ; //声明结构体容器
vector v2 ;
struct stu a1={1,2};
struct stu a2={2,3};
struct stu a3={4,5} ;
v1.push_back( a );
v1.push_back( b );
v1.push_back( c );
//压入数据
v2.push_back( c );
v2.push_back( b );
v2.push_back( a );
//读取出数据
for(int i=0; i
更多的vector 的使用,还得到实际的场景中去实际操作。
set容器
set集合容器使用一种红黑树的平均二叉检索树,不会将重复键值插入,检索使用二叉树的中序遍历,因此可以将元素从小到大排列出来。同时保证数据不重复,可以理解为集合中元素不重复一样
使用时注意包含头文件**#include**
1.set容器的常用操作
s.begin() 返回set容器的第一个元素
s.end() 返回set容器的最后一个元素
s.clear() 删除set容器中的所有的元素
s.empty() 判断set容器是否为空
s.insert() 插入一个元素
s.erase() 删除一个元素
s.size() 返回当前set容器中的元素个数
2.set容器的创建
#include
#include
using namespace std;
int main(){
set s;
}
3.set容器的操作
//插入操作
#include
#include
using namespace std;
int main(){
sets;
int cnt = 1;
s.insert(1);
s.insert(2);
s.insert(5);
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
s.insert(2); //set只允许用一个值出现一次,要插入相同元素请用multiset
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
int a[4] = {11,12,13,14};
s.insert(a,a+4); //将区间[a, a+4]里的元素插入容器
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
return 0;
}
//删除操作
//s.erase() //删除一个元素
#include
#include
using namespace std;
sets;
int main(){
int cnt = 1;
for(int i = 1; i < 11; i++){
s.insert(i);
}
setprint(cnt++);
s.erase(9); //根据元素删除
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
set::iterator ita = s.begin();
set::iterator itb = s.begin();
s.erase(ita); //删除迭代器指向位置的元素
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
ita = s.begin();
itb = s.begin();
itb++;itb++;
s.erase(ita,itb); //删除区间[ita,itb)的元素
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
s.clear();
return 0;
}
//查找操作
//s.find() 查找一个元素,如果容器中不存在该元素,返回值等于s.end()
#include
#include
using namespace std;
sets;
int main(){
int cnt = 1;
s.insert(1);
s.insert(2);
s.insert(5);
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
if(s.find(2) != s.end())
cout << "2 is existent" << endl;
else
cout << "2 is non-existent" << endl;
if(s.find(3) == s.end())
cout << "3 is non-existent" << endl;
else
cout << "2 is existent" << endl;
return 0;
}
//判断元素是否在set中 & 判断set是否为空
#include
#include
#include
using namespace std;
int main(){
set s;
if(s.empty()) cout << "容器为空" << endl;
s.insert(1);
if(!s.empty()) cout << "容器不为空" << endl;
if(s.count(1)) cout << "1在容器中" << endl;
if(!s.count(2)) cout << "2不在容器中" << endl;
return 0;
}
//自定义比较函数
#include
#include
#include
using namespace std;
struct cmp{
bool operator () (const int &a, const int &b){
return a > b;
}
};
sets; //自定义排序函数构造set
int main(){
s.insert(1);
s.insert(2);
s.insert(6);
for(set::iterator it = s.begin(); it!= s.end(); it++)
cout << *it << " ";
return 0;
}
stack容器
stack,俗称为“栈”。可以先去了解一下栈结构再来看看。
由于栈是后进后出的数据结构,因此STL中的stack中只能通过top()来访问栈顶元素。用来模拟实现一些递归。(防止程序对栈内存的限制而导致程序运行错误)
一般来说,程序的栈内存空间很小,若用普通的函数来递归,一旦层数过深,则会导致程序运行崩溃。用栈来模拟递归算法的实现,则可以避免这一方面的问题.
导入前加入头文件#include
常见操作
empty:判断堆栈元素是否为空,true表示栈元素为空;
pop:移除栈顶元素;
push:栈顶添加元素;
top:返回栈顶元素;
size:返回栈中元素数目;
具体实现
#include
#include
using namespace std;
int main(){
stack st;
if(st.empty()==true){//输出Empty
printf("Empty\n");
}else{
printf("Not Empty\n");
}
for(int i = 1; i < 5; i++){
st.push(i);
}
printf("%d\n",st.top);//top()取栈顶元素,输出为5
printf("%d\n",st.size());
for(int i = 1; i < 5; i++){
st.pop(i);
}
printf("%d\n",st.top);//top()取栈顶元素,输出为5
printf%d\n",st.size());
}
queue容器
queue与stack模版非常类似,queue模版也需要定义两个模版参数,一个是元素类型,一个是容器类型,元素类型是必要的,容器类型是可选的,默认为dqueue类型。
队列的知识建议百度搜一下就懂了,提前知道什么是队列再看。
queue q1;
queue q2;
基本操作
入队,如例:q.push(x); 将x 接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()
具体实现
#include
#include
#include
using namespace std;
int main()
{
int e,n,m;
queue q1;
for(int i=0;i<10;i++)
q1.push(i);
if(!q1.empty())
cout<<"dui lie bu kong\n";
n=q1.size();
cout<
队列中还有很多知识,其中最重要的是优先队列,这个要花一些时间去理解,往后再说,同时利用优先队列做的题目也不再少数,很多都是搜索方面的题目,下一次一起拿一些题目一起单独聊聊优先队列和大小堆的知识点