C++:STL 标准模板库容器的使用
一、简介
STL容器:
--> STL:Standard Template Library 标准模板库。
--> 自动申请内容和释放内存,因此无需new和delete操作。
第一类:顺序容器,是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。
--> 容器中元素有固定的位置,除非用插入和删除改变这个位置。
--> 元素的排列次序跟元素值无关,而是由元素添加到容器里的次序决定的。
--> vector【向量-数组】、list【列表-链表】、deque【队列】
<--> vector:初始会分配一个内存大小,空间连续,后续可以自动扩容,是一个动态的数组,只能在末尾添加移除元素, 扩容拷贝是耗时的,但是查询效率高。
<--> list:无需分配指定的内存大小且可以任意伸缩,空间不连续,它主要通过前后指针驱动,可以在头尾添加移除元素,查询较差,但删除和插入灵活,效率高。
<--> deque:结合向量和链表的优势,它是分块的链表和多个数组的联合,进行顺序存储元素,可以在头尾添加移除元素,支持灵活插入和删除,也支持快速查询的能力。
第二类:关联容器,是一种非线性的树结构,更准确的说是二叉树结构。
--> 各元素之间没有严格上的物理顺序,但是元素自身有自己的特点,容器提供了迭代器根据元素的特点"顺序地"获取元素。
--> 元素是有序的集合,默认在插入的时候升序排列。
--> map【映射:key-value,一对一关系】、multimap【可变映射:key-value,一对多关系】、set【集合:value,会去重】、multiset【可变集合:value,可重复】
<--> map:键值对存储,容器内部存储的是一对对key-value,一般通过迭代器去遍历,通过key访问元素值。
<--> set:有序的集合,里面的元素都是排序好的,但是元素不能相同,内部会去重,支持插入,删除,查找等操作。
二、使用
1、vector向量
void vectorTest (void) { //1、Vector容器初始化 vector<int> vec1;//---> 默认初始化,vec1为空。 vector<int> vec2(vec1);//---> 使用vec1进行初始化vec2。 vector<int> vec3(vec1.begin(), vec1.end());//---> 使用vec1进行初始化vec2。 vector<int> vec4(10); //---> 10个值为0的元素 vector<int> vec5(10,4); //---> 10个值为4的元素 vector<string>vec6(10, "张三"); //---> 10个值为张三的元素 //2、Vector容器操作 vec1.push_back(100); //在向量尾部添加元素 int size = (int)vec1.size(); //获取向量元素个数 cout<<"size = "<<size<<endl; bool isEmpty = vec1.empty(); //判断向量是否为空 cout<<"isEmpty = "<<isEmpty<<endl; vec1.insert(vec1.end(), 5, 3);//从vec1.back位置插入5个值为3的元素 cout<<"size = "<<(int)vec1.size()<<endl; vec1.pop_back();//删除向量末尾的元素 cout<<"size = "<<(int)vec1.size()<<endl; vec1.erase(vec1.begin(), vec1.end());//删除向量两个位置之间的元素,其他元素前移 cout<<"size = "<<(int)vec1.size()<<endl; bool isEqual = (vec1==vec2); //判断向量是否相等==、!=、>=、<= cout<<"isEqual = "<<isEqual<<endl; vec1.clear(); //清空向量元素 cout<<"size = "<<(int)vec1.size()<<endl; //3、Vector向量遍历 cout<<"item1 = "; for (int i=0; i<vec5.size(); i++) { //普通角标遍历 cout << vec5[i] << " "; } cout<<endl; cout<<"item2 = "; vector<int>::iterator iter = vec5.begin();//获取向量迭代器【首地址】---- 可以访问元素的同时还可以更改元素的值。vec5.end()表示尾部元素的下一个元素,作为结束标识符,无需打印。 for (; iter != vec5.end(); iter++) { cout << *iter << " "; } cout<<endl; cout<<"item3 = "; vector<string>::const_iterator const_iter = vec6.begin(); //获取const类型的迭代器【首地址】---- 可以访问元素,但是不能更改元素的值 for (; const_iter != vec6.end(); const_iter++) { cout << *const_iter << " "; } cout<<endl; }
size = 1 isEmpty = 0 size = 6 size = 5 size = 0 isEqual = 1 size = 0 item1 = 4 4 4 4 4 4 4 4 4 4 item2 = 4 4 4 4 4 4 4 4 4 4 item3 = 张三 张三 张三 张三 张三 张三 张三 张三 张三 张三 Program ended with exit code: 0
2、list列表
void listTest (void) { //1、List容器初始化 list<int> list1;//创建空的list1 list<int> list2(10); //创建含有10个元素的list2 list<int> list3(4,20); //创建含有4个值为20的元素的list3 list<string> list4(5,"XYQ"); //创建含有5个值为"XYQ"的元素的list4 list<string> list5(list4); //使用list4初始化list5 list<string> list6(list5.begin(), list5.end());//使用list5初始化list6 //2、List容器操作 list1.assign(list3.begin(), list3.end()); // 分配值 cout << "size = " << list1.size()<<endl; list1.push_back(10); //尾部添加值 cout << "size = " << list1.size()<<endl; list1.pop_back();//删除末尾的值 cout << "size = " << list1.size()<<endl; list1.push_front(100);//头部添加值 cout << "size = " << list1.size()<<endl; list1.pop_front();//头部删除值 cout << "size = " << list1.size()<<endl; list1.clear();//清空元素 cout << "size = " << list1.size()<<endl; bool isEmpty = list1.empty();//是否为空 cout << "isEmpty = " << isEmpty <<endl; string str1 = list4.front(); //访问首个元素 cout << "str1 = " << str1 <<endl; string str2 = list4.back(); //访问尾部元素 cout << "str2 = " << str2 <<endl; list<string>::iterator iter1 = list4.begin(); //访问迭代器首地址 cout << "*iter1 = " << *iter1 <<endl; list<string>::iterator iter2 = list4.end(); list4.insert(iter2, "YUAN");//在指定迭代器后面插入元素 cout << "size = " << list4.size()<<endl; list4.insert(iter1, 3, "ZZZ");//从指定位置插入3个值为QUAN的元素 cout << "size = " << list4.size()<<endl; list<string>::reverse_iterator re_iter = list4.rbegin();//访问迭代器反转后的首地址 cout << "*re_iter = " << *re_iter <<endl; cout << "before list5 size = " << list5.size()<<endl; list5.remove("XYQ");//相同的元素全部删除 cout << "after list5 size = " << list5.size()<<endl; //3、List容器遍历 cout<<"item1 = "; for (list<string>::const_iterator iter=list4.begin(); iter != list4.end(); iter++) { cout << *iter << " "; } cout<<endl; //排序后遍历 cout<<"item2 = "; list4.sort(); for (list<string>::const_iterator iter=list4.begin(); iter != list4.end(); iter++) { cout << *iter << " "; } cout<<endl; //反转后遍历 cout<<"item3 = "; list4.reverse(); for (list<string>::const_iterator iter=list4.begin(); iter != list4.end(); iter++) { cout << *iter << " "; } cout<<endl; }
size = 4 size = 5 size = 4 size = 5 size = 4 size = 0 isEmpty = 1 str1 = XYQ str2 = XYQ *iter1 = XYQ size = 6 size = 9 *re_iter = YUAN before list5 size = 5 after list5 size = 0 item1 = ZZZ ZZZ ZZZ XYQ XYQ XYQ XYQ XYQ YUAN item2 = XYQ XYQ XYQ XYQ XYQ YUAN ZZZ ZZZ ZZZ item3 = ZZZ ZZZ ZZZ YUAN XYQ XYQ XYQ XYQ XYQ Program ended with exit code: 0
3、deque队列
void dequeTest(void) { //deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。 //与vector不同的是,deque还支持从开始端插入数据:push_front()。其余类似vector操作方法的使用。 //1、Deque容器初始化 deque<int> deque1; //初始化空的队列 //2、Deque容器操作 deque1.push_back(100); // 在队列尾部添加元素 cout<<"size = "<<deque1.size()<<endl; deque1.push_front(80); // 在队列头部插入元素 cout<<"size = "<<deque1.size()<<endl; bool isEmpty = deque1.empty(); // 队列是否为空 cout<<"isEmpty = "<<isEmpty<<endl; for (int i=0; i<deque1.size(); i++) { //普通角标遍历 cout<<"item = "<< deque1[i] <<endl; } deque<int>::iterator iter = deque1.begin(); //获取队列迭代器首地址 cout<<"*iter = "<< *iter <<endl; deque1.insert(iter+2, 1000); //在执行迭代器位置添加元素 cout<<"size = "<<deque1.size()<<endl; for (; iter != deque1.end(); iter++) { cout<<"iter = "<< *iter <<endl; } int value = deque1.at(2);//获取指定位置元素 cout<<"value = "<<value<<endl; deque1.pop_front(); // 从队列中移除首个元素 cout<<"size = "<<deque1.size()<<endl; deque1.pop_back(); // 从队列中移除尾部元素 cout<<"size = "<<deque1.size()<<endl; deque1.clear(); //清空队列元素 cout<<"size = "<<deque1.size()<<endl; }
size = 1 size = 2 isEmpty = 0 item = 80 item = 100 *iter = 80 size = 3 iter = 80 iter = 100 iter = 1000 value = 1000 size = 2 size = 1 size = 0 Program ended with exit code: 0
4、map映射
void mapTest(void) { map<string, int> map1; //初始化空的map map1.insert(make_pair("sex", 1)); //插入元素 cout<<"size = "<<map1.size()<<endl; map1.insert(pair<string, int>("age",30));//插入元素 cout<<"size = "<<map1.size()<<endl; map1.insert(map<string,int>::value_type("height", 178));//插入元素 cout<<"size = "<<map1.size()<<endl; int age = map1.at("age"); //取出元素值 cout<<"age = "<<age<<endl; map<string,int>::iterator iter_map = map1.find("sex"); //获取指定的迭代器 string key = iter_map->first; //取得key int value = iter_map->second; //取得value cout<<"key = "<<key<<", "<<"value ="<<value<<endl; for (map<string,int>::const_iterator const_iter_map = map1.begin(); const_iter_map != map1.end(); const_iter_map++) { //遍历 string key = const_iter_map->first; //取得key int value = const_iter_map->second; //取得value cout<<"key = "<<key<<", "<<"value ="<<value<<endl; } map1.erase(iter_map); //删除迭代器数据 cout<<"size = "<<map1.size()<<endl; map1.erase("age"); //根据key删除value cout<<"size = "<<map1.size()<<endl; map1.clear();// 清空所有元素 cout<<"size = "<<map1.size()<<endl; bool isEmpty = map1.empty(); //是否为空 cout<<"isEmpty = "<<isEmpty<<endl; }
size = 1 size = 2 size = 3 age = 30 key = sex, value =1 key = age, value =30 key = height, value =178 key = sex, value =1 size = 2 size = 1 size = 0 isEmpty = 1 Program ended with exit code: 0
5、set集合
void setTest(void) { set<string> set1; //初始化空的set1 set1.insert("zhangsan");//插入元素 set1.insert("lisi"); //插入元素 set1.insert("wangwu");//插入元素 set1.insert("zhangsan");//插入元素,会去重 cout<<"size = "<<set1.size()<<endl; int count = (int)set1.count("zhangsan");//返回该元素存在的个数,去重的原因,只能为1或者0。 cout<<"count = "<<count<<endl; set<string>::iterator set_iter = set1.find("zhangsan"); //返回指定迭代器的地址 cout<<"set_iter = "<<*set_iter<<endl; for (set<string>::const_iterator const_set_iter = set1.begin(); const_set_iter != set1.end(); const_set_iter++) { //迭代器遍历 cout<<"item = "<<*const_set_iter<<endl; } set1.erase(set_iter); //删除迭代器数据 cout<<"size = "<<set1.size()<<endl; set1.erase("lisi"); //删除value cout<<"size = "<<set1.size()<<endl; set1.clear();// 清空所有元素 cout<<"size = "<<set1.size()<<endl; bool isEmpty = set1.empty(); //是否为空 cout<<"isEmpty = "<<isEmpty<<endl; }
size = 3 count = 1 set_iter = zhangsan item = lisi item = wangwu item = zhangsan size = 2 size = 1 size = 0 isEmpty = 1 Program ended with exit code: 0