一、简介

STL容器:

标准模板库。

    --> 自动申请内容和释放内存,因此无需new和delete操作。

 

第一类:顺序容器,是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。

    --> 容器中元素有固定的位置,除非用插入和删除改变这个位置。

    --> 元素的排列次序跟元素值无关,而是由元素添加到容器里的次序决定的。

-数组】、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

 

 

程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!