C++STL标准库学习笔记(十)vector deque list
前言:
在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来。
在这一篇文章中,我们主要对vector deque list进行简单的介绍,(真的很简单的介绍,如果想要知道所有函数的用法的话,建议去看一下其他人的总结,我这里主要是记录一个学习过程,提供一个学习思路)
因为它们的操作大多相同,就不一个个列举它们的操作了,一个优秀的IDE能自动提示“.”后面应该接什么,函数里面应该填什么,反复强调已经了解过的知识就有点冗杂了。
正文:
1. vector示例程序
1 #include2 #include 3 using namespace std; 4 template<class T> 5 void PrintVector(T s, T e) 6 { 7 for (; s != e; s++) 8 { 9 cout<<* s<<" "; 10 } 11 cout<<endl; 12 } 13 14 int main(int argc, char const *argv[]) 15 { 16 int a[5] = {1,2,3,4,5}; 17 vector<int> v(a,a+5); 18 //用数组来构造vector 19 cout<<"1)"< //结果:1)5 20 cout<<"2)"; 21 PrintVector(v.begin(),v.end());//结果:2)1 2 3 4 5 22 v.insert(v.begin() + 2, 13); 23 //在第二个元素后面插入元素 24 cout<<"3)"; 25 PrintVector(v.begin(),v.end());//结果:3)1 2 13 3 4 5 26 v.erase(v.begin() + 2); 27 //删除迭代器指向的元素 28 cout<<"4)"; 29 PrintVector(v.begin(),v.end());//结果:4)1 2 3 4 5 30 vector<int> v2(4,100); 31 //构造函数,创造四个元素值为100的vector 32 v2.insert(v2.begin(),v.begin() + 1,v.begin() + 3);//将v的一段插入v2的开头 33 cout<<"5) v2:"; 34 PrintVector(v2.begin(),v2.end());//结果:5) v2:2 3 100 100 100 100 35 v2.erase(v.begin()+1, v.begin()+3); 36 //删除了v的一个区间,即2,3 37 cout<<"6)"; 38 PrintVector(v.begin(),v.end());//结果:6)1 4 5 39 return 0; 40 }
老样子,找出其中重要的部分来细锁。
int a[5] = {1,2,3,4,5};
vector
这里是建立了一个int数组,然后用这个数组来创造一个vector。
v.end() - v.begin()
这个在这个程序中的结果是5,说明vector的迭代器是随机访问迭代器,毕竟只有它才能实现加减操作。
v.insert(v.begin() + 2, 13);
在第二个元素后面插入13(不就是在下标2插入元素然后后面的元素集体后移吗),没什么需要特别强调的。
v.erase(v.begin() + 2);
删除第二个元素后面(不就是下标为2的元素吗)的元素。
vector
构造函数,v2包含四个值为100的元素。(充分体现了STL标准库的聪明机智,直接省去麻烦的一个个赋值)
v2.insert(v2.begin(),v.begin() + 1,v.begin() + 3);
在v2的开头插入v的下标为1到下标为2(1和3的左闭右开区间)的元素。(STL标准库普遍如此)
v2.erase(v.begin()+1, v.begin()+3);
擦去下标为1和2的元素([1,3)的元素)
2. 用vector实现二维数组
样例:
1 #include2 #include 3 using namespace std; 4 5 int main(int argc, char const *argv[]) 6 { 7 vector int>>v(3); 8 //v有3个元素,每个元素都是vector 容器 9 for (int i = 0; i < v.size(); i++) 10 { 11 for (int j = 0; j < 4; j++) 12 { 13 v[i].push_back(j); 14 } 15 } 16 for (int i = 0; i < v.size(); i++) 17 { 18 for (int j = 0; j < 4; j++) 19 { 20 cout<" "; 21 } 22 cout<<endl; 23 } 24 /* 25 结果: 26 0 1 2 3 27 0 1 2 3 28 0 1 2 3 29 */ 30 return 0; 31 }
从本质上来看,就是套娃,但是它的元素可以通过v[i][j]来调用,可以说是非常方便的
注意:
vector
在定义时,里面的vector
3. deque
双向队列
所有适用于vector的操作都适用于deque
deque还有push_front(将元素插入到前面)和pop_front(删除最前面的元素)操作,复杂度是O(1)
4. list容器
双向链表
它的底层实现不是数组,所以不支持随机存取
在任何位置插入删除都是常数时间,不支持随机存取
除了具有所有顺序容器都具有的成员函数以外(差不多vector有的它都有),还支持8个成员函数:
push_front:在前面插入
pop_front:删除前面的元素
sort:排序(list不支持STL的算法sort)(毕竟这是list,而不是数组之类,STL库的sort算法只支持可以随机访问的迭代器)
remove:删除和指定值相等的所有元素
unique:删除所有和前一个元素相同的元素(要做到元素不重复,则unique之前还需要sort)
merge:合并两个链表,并清空被合并的那个
reverse:颠倒链表
splice:在指定位置前面插入另一链表中的一个或多个元素,并在另一链表中删除被插入的元素
样例:

1 #include样例32 #include
3 #include 4 using namespace std; 5 6 class A 7 { 8 private: 9 int n; 10 public: 11 A(int n_) { n = n_;} 12 friend bool operator<( const A & a1, const A & a2); 13 friend bool operator==( const A & a1, const A & a2); 14 friend ostream & operator<<( ostream & o, const A & a); 15 }; 16 bool operator<(const A & a1, const A & a2) 17 { 18 return a1.n < a2.n; 19 } 20 bool operator==(const A & a1, const A & a2) 21 { 22 return a1.n == a2.n; 23 } 24 ostream & operator<<( ostream & o, const A & a) 25 { 26 o << a.n; 27 return o; 28 } 29 template<class T> 30 void PrintList(const list & lst) 31 {//不推荐的写法,还是用两个迭代器作为参数会更好 32 typename list ::const_iterator i; 33 i = lst.begin(); 34 for ( i = lst.begin(); i != lst.end(); i++) 35 { 36 cout<< *i << ","; 37 } 38 //typename可以用来说明list ::const_iterator是个类型 39 //在vs中不写也可以 40 } 41 42 43 44 int main(int argc, char const *argv[]) 45 { 46 list lst1,lst2; 47 lst1.push_back(1); 48 lst1.push_back(2); 49 lst1.push_back(3); 50 lst1.push_back(4); 51 lst1.push_back(2); 52 53 lst2.push_back(10); 54 lst2.push_front(20); 55 lst2.push_back(30); 56 lst2.push_back(30); 57 lst2.push_back(30); 58 lst2.push_front(40); 59 lst2.push_back(40); 60 61 cout<<"1)"; 62 PrintList(lst1); 63 cout<//输出:1)1,2,3,4,2, 64 cout<<"2)"; 65 PrintList(lst2); 66 cout< //输出:2)40,20,10,30,30,30,40, 67 68 lst2.sort(); 69 cout<<"3)"; 70 PrintList(lst2); 71 cout< //输出:3)10,20,30,30,30,40,40, 72 73 lst2.pop_front(); 74 cout<<"4)"; 75 PrintList(lst2); 76 cout< //输出:4)20,30,30,30,40,40, 77 78 lst1.remove(2);//删除所有和A(2)相等的元素 79 cout<<"5)"; 80 PrintList(lst1); 81 cout< //输出:5)1,3,4, 82 83 lst2.unique();//删除所有和前一个元素相等的元素 84 cout<<"6)"; 85 PrintList(lst2); 86 cout< //输出:6)20,30,40, 87 88 lst1.merge(lst2);//合并lst2到lst1并清空lst2 89 cout<<"7)"; 90 PrintList(lst1); 91 cout< //输出:7)1,3,4,20,30,40, 92 93 cout<<"8)"; 94 PrintList(lst2); 95 cout< //输出:8) 96 97 lst1.reverse(); 98 cout<<"9)"; 99 PrintList(lst1); 100 cout< //输出:9)40,30,20,4,3,1, 101 102 lst2.push_back(100); 103 lst2.push_back(200); 104 lst2.push_back(300); 105 lst2.push_back(400); 106 list::iterator p1,p2,p3; 107 p1 = find(lst1.begin(),lst1.end(),3); 108 p2 = find(lst2.begin(),lst2.end(),200); 109 p3 = find(lst2.begin(),lst2.end(),400); 110 lst1.splice(p1,lst2,p2,p3); 111 //将[p2,p3)插入p1之前,并从lst2中删除[p2,p3) 112 113 cout<<"10)"; 114 PrintList(lst1); 115 cout< //输出:10)40,30,20,4,200,300,3,1, 116 cout<<"11)"; 117 PrintList(lst2); 118 cout< //输出:11)100,400, 119 120 return 0; 121 }
这个样例基本把list的主要用法都包含进去了。
后记:
这些东东基本上都是那种你知道了一个,其他的就都能推导出来的那种知识,如果不想死记硬背的话,其实用好IDE自带的功能,记好基本的用法就能自由使用了。放假了,不能摸鱼,要认真学习,为将来做好准备(生怕被淘汰的我)。