C++ 顺序容器
想吃读研的 人气:0一: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 }
加载全部内容