C++进阶与拔高(十)(C++ STL)(vector,list,stack和queue接口操作)

第五章 STL 容器的具体用法

5.1 vector用法总结

5.1.1 介绍

       vector可以用来表示一个不定长度的数组,它是一种序列容器。就像数组一样,vector也采用连续的存储空间来存储元素,其中重载了下标操作符“[ ]”,可以对vector元素进行访问。与数组不同的是它的大小是可以动态改变的。当新元素插入容器时,vector不会每次都重新分配大小。与其他动态序列容器相比,vector在访问元素时更加高效,在末尾添加和删除元素相对高效。

5.1.2 声明、初始化及基本操作

#include<vector>  //包含头文件
vector<int> vec;  //声明一个int型向量
vector<int> vec(5);//声明一个初始大小为5的int向量
vector<int> vec(10,1);//声明一个初始大小为10且值均为1的向量
vector<int> vec(tmp);//声明并用tmp向量初始化vec向量
vec.size();//返回向量大小(容量)
vec.max_size();//返回向量的最大容量
vec.capacity();//向量真实大小
vec.empty();//判断向量是否为空
vec.shrink_to_fit();//减少向量大小到满足所占存储空间的大小
vec.push_back();//向量末尾插入元素
vec.pop_back();//删除向量末尾元素
vec.insert(vec.begin()+i,a);//在第i+1个元素前面插入a,通过迭代器操作
vec.erase(vec.begin()+i);//删除第i+1个元素,通过迭代器操作
vec.clear();//清除向量中所有元素
vec[1];//下标法访问向量的第一个元素
vec.at(1);//at法访问向量的第一个元素,如果越界会抛出异常
//遍历元素(迭代器法)
vector<int>::iterator it;//定义int型向量的迭代器it
for(it=vec.begin();it!=vec.end();it++)
cout<<*it<<endl;
//遍历元素(下标法)
for(size_t i=0;i<vec.size();i++)
cout<<vec.at(i)<<endl;
//算法
#include<algorithm>
resverse(vec.begin(),vec,end());//元素反向排列
sort(vec.begin(),vec.end());//将元素从小到大排序
//从大到小排序
bool Comp(const int& a, const int& b) {
return a > b;
}
sort(vec.begin(), vec.end(), Comp);

5.2 list用法总结

        相对于vector容器的连续线性空间,list是一个双向链表,它有一个重要性质:插入操作和删除操作都不会造成原有的list迭代器失效,每次插入或删除一个元素就配置或释放一个元素空间。也就是说,对于任何位置的元素插入或删除,list永远是常数时间。使用list容器之前必须加上<vector>头文件:#include<list>。list属于std命名域的内容,因此需要通过命名限定:using std::list;也可以直接使用全局的命名空间方式:using namespace std;

#include<vector>
#include<list>
list<int> list1;//定义一个int类型的列表
list<int> list1(3);//创建一个初始大小为3的int型列表
list<int> list1(3,2);//建立一个含3个元素的列表,值都是2
list<int> list2(list1);//建立一个列表list2,它是list1的拷贝
//插入函数类似于vector
list1.push_back();//在列表尾部插入元素
list1.push_front();//在开始位置增加一个元素
list1.pop_back();//删除末尾元素
list1.pop_front();//删除第一个元素
list1.front();//返回列表list1的第一个元素
list1.back();//返回列表list1的最后一个元素
list1.empty();//判断列表是否为空
list1.size();//返回列表list1中实际元素个数
list1.clear();//清除列表中所有元素
list1.remove(2);//删除列表中值为2的所有元素(可以是其他类型)
list1.insert(list1.begin()+i,a); //在第i+1个元素前面插入a,通过迭代器操作
list1.erase(list1.begin()+i);//删除第i+1个元素,通过迭代器操作
//用迭代器遍历元素
list<int>::iterator it2;
for(it2=list1.begin();it2!=list1.end();it2++)
cout<<*it2<<endl;
#include<algorithm>
swap(list1,list2);//将list1和list2交换
list1.merge(list2);//合并2个有序的列表,从新放到list1中,释放list2
list1.splice(list1.begin(),list2);//将list2连接到list1的begin()位置
list1.reverse();//反转列表
list1.sort();//升序排序

5.3 stack用法总结

       栈是一个线性表,插入和删除只在表的一端进行。这一端称为栈顶(Stack Top),另一端则为栈底(Stack Bottom)。堆栈的元素插入称为入栈,元素的删除称为出栈。由于元素的入栈和出栈总在栈顶进行,因此,堆栈是一个后进先出(Last In First Out)表,即 LIFO 表。

       C++ STL 的栈泛化是直接通过现有的序列容器来实现的,默认使用双端队列deque的数据结构,当然,可以采用其他线性结构(vector 或 list等),只要提供栈的入栈、出栈、栈顶元素访问和判断是否为空的操作即可。由于栈的底层使用的是其他容器,因此,栈可看做是一种适配器,将一种容器转换为另一种容器(堆栈容器)。

       为了严格遵循栈的数据后进先出原则,stack 不提供元素的任何迭代器操作,因此,stack 容器也就不会向外部提供可用的前向或反向迭代器类型。

#include<stack>
stack<int> s1;//定义一个类型为int型的栈
s.push(i);//入栈操作,在栈顶增加元素
s.pop();//出栈,移除栈顶元素
s.top();//取栈顶元素,返回栈顶元素的值
s.empty();//判断栈是否为空,若是则返回一
s.size();//返回栈中元素的个数
//清空栈中元素
while(!s.empty())
{s.pop();}

5.4 queue用法总结

5.4.1 一般队列

#include<queue>
queue<int> q1;//定义一个类型为int的队列
q1.push(x);//将x连接到队列的尾端
q1.pop();//弹出队列的第一个元素,但并不返回它
q1.front();//返回队首元素
q1.back();//返回队尾元素
q1.empty();//判断队列是否为空,若是返回1
q1.size();//返回队列长度
//定义一个元素为结构体的队列
struct node
{int x,y;};
queue<node> q;

5.4.2 优先级队列

       优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大互小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。

#include<queue>
priority_queue<int> q;//声明一个优先级队列q,类型为int型。这个优先级队列中元素按照从大到小的顺序出队
//下面接口定义同上
q.empty();
q.pop();
q.push(x);
q.size();
q.top();//返回优先级队列中的队顶元素

猜你喜欢

转载自blog.csdn.net/Lao_tan/article/details/81292937