C++顺序容器(vector、deque、list)的使用详解
作者:想吃读研的
一:STL(Standard Template Library),即标准模板库,是一个高效的C++程序库
1.从实现层次看,整个STL是以一种类型参数化(type parameterized)的方式实现的,基于模板(template)。
2.从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming),在这种思想里,大部分基本算法被抽象,被泛化,独立于与之对应的数据结构,用于以相同或相近的方式处理各种不同情形。
二:STL组件
1.Container(容器) 各种基本数据结构
2.Algorithm(算法) 各种基本算法如 sort search等
3.Iterator(迭代器) 连接containers 和 algorithms
4.了解:
- Adapter(适配器) 可改变containers或function object接口的一种组件
- Function object(函数对象) *
- Allocator(分配器)*
三:容器
1.容器类是容纳、包含一组元素或元素集合的对象
2.七种基本容器:
向量(vector)、双端队列(deque)、链表(list)、集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)
四:类型成员
1.循环子操作:
- begin():指向第一个元素
- end():指向最后一个元素的后一个位置
- rbegin():指向逆序的第一个元素
- rend():指向逆序的最后一个元素的后一个位置
2.访问元素操作
- front():访问第一个元素
- back():访问最后一个元素
- [ ]:无测试的下标访问(不用于 list)
- at():有测试的下标访问(只用于 vector 和 deque)
3.堆栈和队列操作
- push_back():将新元素加入到尾部
- pop_back():移出最后一个元素
- push_front():将新元素加入头部(只用于 list 和 deque)
- pop_front():移出第一个元素(只用于 list 和 deque)
4.表操作
- insert(p,x):将元素x加入到 p 之前
- erase(p):删除p处的元素
- clear():清除所有的元素
五:迭代器
迭代器是面向对象版本的指针,它们提供了访问容器、序列中每个元素的方法
六:顺序容器
顺序容器的接口
1.插入方法:push_front(),push_back(),insert(),运算符“=”
2.删除方法:pop() ,erase(),clear()
3.迭代访问方法:使用迭代器
4.其他顺序容器访问方法(不修改访问方法):front(),back(),下标[ ]运算符
七:顺序容器--向量(vector)
a.向量属于顺序容器,用于容纳不定长线性序列(即线性群体),提供对序列的快速随机访问(也称直接访问)
b.数据结构很像一个数组,所以与其他容器相比,vector 能非常方便和高效访问单个元素,支持随机访问迭代子
c.向量是动态结构,它的大小不固定,可以在程序运行时增加或减少
d.与数组不同,向量的内存用尽时,向量自动分配更大的连续内存区,将原先的元素复制到新的内存区,并释放旧的内存区。这是向量类的优点。
头文件:#include <vector>
例子:
1.push_back尾部添加
#include<iostream> using namespace std; #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<int> v; //迭代器 vector<int>::iterator it; it = v.begin(); //开始位置 //在尾部添加 v.push_back(1); v.push_back(12); //迭代器指针 遍历向量容器 for(it = v.begin();it<v.end();it++) { cout<<" "<<*it; //取值 } // 1 12 cout<<endl; }
2.insert按照位置插入
#include<iostream> using namespace std; #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<int> v; //迭代器 vector<int>::iterator it; it = v.begin(); //开始位置 //在尾部添加 v.push_back(1); v.push_back(12); //按照位置插入 v.insert(v.begin(),100); for(it = v.begin();it<v.end();it++) { cout<<" "<<*it; //取值 } // 100 1 12 cout<<endl; }
3.获取id(成员属性)
CStaff.h
#ifndef CSTAFF_H #define CSTAFF_H #define ADMIN 1 #define MANAGER 2 #define WAITER 3 #include<string> #include<iostream> using namespace std; class Staff { public: Staff(); Staff(int id,string name,string pwd,int prole); ~Staff(); int getId(); string getName(); string getPwd(); int getRole(); private: int ID; string name; string pwd; int role; }; #endif
CStaff.cpp
#include"CStaff.h" #include<iostream> using namespace std; Staff::Staff() { } Staff::Staff(int id,string name,string pwd,int prole) { this->ID = id; this->name = name; this->pwd = pwd; this->role = prole; } int Staff::getId() { return this->ID; } string Staff::getName() { return this->name; } string Staff::getPwd() { return this->pwd; } int Staff::getRole() { return this->role; } Staff::~Staff() { }
main.cpp
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); staffV.insert(staffV.begin(),new Staff(1003,"sam","1234",MANAGER)); for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } // id:1003 // id:1001 // id:1002 }
4.按照位置插入insert --- 需要迭代器指针it++偏移
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //id:1001 //id:1003 //id:1002 }
5.尾部删除pop_back
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //尾部删除 staffV.pop_back(); for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } // id:1001 // id:1003 }
6. erase按照位置删除
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //尾部删除 staffV.pop_back(); it = staffV.begin(); //开始位置 staffV.erase(it);//删除第一个 for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //id:1003 }
7.erase按照位置删除(迭代器指针偏移it++)
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //尾部删除 staffV.pop_back(); it = staffV.begin(); //开始位置 it++; staffV.erase(it);//删除第二个 for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //id:1001 }
8.size计数
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"员工数量:"<<staffV.size()<<endl; for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //员工数量:3 //id:1001 //id:1003 //id:1002 }
9.容器访问四种
1.迭代器指针 2.at访问方式 3.[ ]中括号访问方式 4.C++新增auto访问方式
at访问方式:
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"员工数量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下标法 { cout<<"id:"<<staffV.at(i)->getId()<<endl; } //员工数量:3 //id:1001 //id:1003 //id:1002 }
[ ]中括号访问方式
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"员工数量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下标法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } //员工数量:3 //id:1001 //id:1003 //id:1002 }
10.clear清空
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"员工数量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下标法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } staffV.clear(); cout<<"员工数量:"<<staffV.size()<<endl; //员工数量:3 //id:1001 //id:1003 //id:1002 //员工数量:0 }
八:顺序容器--双端队列--deque
a.双端队列是一种放松了访问权限的队列。元素可以从队列的两端入队和出队,也支持通过下标操作符“[]”进行直接访问。
b.与向量的对比 功能上:和向量没有多少区别,
性能上:在双端队列起点上的插入和删除操作快
头文件:#include <deque>
1.push_front头部插入
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> void demo_deque(); int main() { demo_deque(); return 0; } void demo_deque() { deque<Staff *> staffV; deque<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //开始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //头部插入 staffV.push_front(new Staff(1004,"lilei","1234",MANAGER)); cout<<"员工数量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下标法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } // staffV.clear(); // cout<<"员工数量:"<<staffV.size()<<endl; //员工数量:4 //id:1004 //id:1001 //id:1003 //id:1002 }
2.pop_front头部删除
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> void demo_deque(); int main() { demo_deque(); return 0; } void demo_deque() { deque<Staff *> staffV; deque<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); //头部插入 staffV.push_front(new Staff(1004,"lilei","1234",MANAGER)); it = staffV.begin(); //开始位置 //it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); // 3 4 1 2 staffV.pop_front(); //头部删除 cout<<"员工数量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下标法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } // staffV.clear(); // cout<<"员工数量:"<<staffV.size()<<endl; //员工数量:3 //id:1004 //id:1001 //id:1002 }
九:顺序容器 --列表--list
a.链表主要用于存放双向链表,可以从任意一端开始遍历。链表还提供了拼接(splice)操作,将一个序列中的元素从插入到另一个序列中。
b.对比:元素的插入和删除操作对 list 而言尤为高效
与 vector 和 deque 相比,对元素的下标访问操作的低效是不能容忍的,因此 list 不提供这类操作。
头文件:#include <list>
list只支持迭代器法
for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历
1.只支持迭代器指针遍历
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> #include<list> void demo_list(); int main() { demo_list(); return 0; } void demo_list() { list<Staff *> staffList; list<Staff *>::iterator it; staffList.push_back(new Staff(1001,"admin","1234",ADMIN)); staffList.push_back(new Staff(1002,"lily","1234",ADMIN)); //头部插入 staffList.push_front(new Staff(1004,"lilei","1234",MANAGER)); it = staffList.begin(); //开始位置 //it++; //按照位置插入 staffList.insert(it,new Staff(1003,"sam","1234",MANAGER)); // 3 4 1 2 staffList.pop_front(); //头部删除 cout<<"员工数量:"<<staffList.size()<<endl; for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; } //员工数量:3 //id:1004 //id:1001 //id:1002 }
2.把一个链表(单个元素)里的东西放到另外一个链表中--splice
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> #include<list> void demo_list(); int main() { demo_list(); return 0; } void demo_list() { list<Staff *> staffList; list<Staff *> list2;//再一个链表 list2.push_back(new Staff(1006,"mei","1234",ADMIN));//有一个1006 staffList.push_back(new Staff(1001,"admin","1234",ADMIN)); staffList.push_back(new Staff(1002,"lily","1234",ADMIN)); //头部插入 staffList.push_front(new Staff(1004,"lilei","1234",MANAGER)); list<Staff *>::iterator it; it = staffList.begin(); //开始位置 it++; //在第二个位置插入1006 //splice move element from list to list staffList.splice(it,list2); cout<<"员工数量:"<<staffList.size()<<endl; for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; } cout<<"员工数量:"<<list2.size()<<endl; //员工数量:4 //id:1004 //id:1006 //id:1001 //id:1002 //员工数量:0 } #include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> #include<list> void demo_list(); int main() { demo_list(); return 0; } void demo_list() { list<Staff *> staffList; list<Staff *>list2;//再一链表 list2.push_back(new Staff(1006,"mei","1234",ADMIN)); //有1006 1007 list2.push_back(new Staff(1007,"didi","1234",ADMIN)); staffList.push_back(new Staff(1001,"admin","1234",ADMIN)); staffList.push_back(new Staff(1002,"lily","1234",ADMIN)); //头部插入 staffList.push_front(new Staff(1004,"lilei","1234",MANAGER)); list<Staff *>::iterator it; it = staffList.begin(); //开始位置 it++; //在第二个位置插入1006 1007 //splice move element from list to list staffList.splice(it,list2); cout<<"员工数量:"<<staffList.size()<<endl; for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历 { cout<<"id:"<<(*it)->getId()<<endl; } cout<<"员工数量:"<<list2.size()<<endl; //员工数量:5 //id:1004 //id:1006 //id:1007 //id:1001 //id:1002 //员工数量:0 }
到此这篇关于C++顺序容器(vector、deque、list)的使用详解的文章就介绍到这了,更多相关C++ 顺序容器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!