STL标准库设计原理与使用

STL是C++标准库的一部分,包括容器(如vector、list、deque)、算法和迭代器等组件。它利用模板实现了常用数据结构和算法。内存分配采用两级配置器,小内存使用内存池技术。常见的头文件如< algorithm >、< vector >等。STL容器包括序列式容器(如数组、vector、string、list、forward_list和deque)和关联式容器(如set、map、unordered_set和unordered_map)。此外,STL还提供了丰富的算法,如排序、查找、变换等。
摘要由CSDN通过智能技术生成

目录

简介

1.1 STL的版本

1.2 STL的组成

STL六大组件

内存分配

常用头文件

容器与数据结构

序列式容器

2.1 数组类容器

2.1.1 vector

2.1.2 array

2.1.3 string

2.2 链表类容器

2.2.1 list

2.2.2 forward_list

2.3 队列类容器

2.3.1 deque

2.3.2 stack

2.3.3 queue

2.4 堆容器 priority_queue

关联式容器

3.1 set

3.2 map

无序关联式容器

4.1 unordered_set

4.2 unordered_map

常用算法

5.1 非质变算法

5.2 质变算法

5.3 排序和查找算法

参考资料


  1. 简介

    STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。STL 是 C++ 标准库的一部分,不用单独安装,命名空间std。

    C++ 对模板(Template)支持得很好,STL 就是借助模板把常用的数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。

    STL 是一些容器、算法和其他一些组件的集合,它位于各个 C++ 的头文件中,以源代码的形式提供。

    1.1 STL的版本

    STL是一个标准,只规定了STL的接口,内部实现没有要求。STL有许多实现版本:

    SGI STL版本注释丰富,结构清晰,可读性较强,GNU STL是基于SGI版本开发的,所以是最流行的版本。

    CLANG 中使用的是LLVM STL, mac os中用的就是LLVM STL。

    1.2 STL的组成

    STL六大组件

    • 容器(containers) 一些封装数据结构的模板类,例如 vector 向量容器、list 列表容器等。

    • 算法(algorithms)STL 提供的数据结构算法,被设计成一个个的模板函数,大部分算法都包含在头文件 <algorithm> 中,少部分位于头文件 <numeric> 中。

    • 迭代器(iterators)对容器中数据的读和写,是通过迭代器完成的,它扮演着容器和算法之间的胶合剂

    • 仿函数(functors)一个类将 () 运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象(又称仿函数)。

    • 配接器(adapters)使一个类的接口(模板的参数)适配成用户指定的形式,从而让原本不能在一起工作的两个类工作在一起。

    • 配置器(allocators)又叫内存分配器,为容器类模板提供自定义的内存申请和释放功能,内存分配器对于一般用户来说,并不常用。

       

      内存分配

      为了减小内存碎片问题,SGI STL采用了两级配置器:

      • 当分配的空间大小超过128 bytes时,会使用第一级空间配置器。第一级空间配置器直接使用malloc()、realloc()、free()函数进行内存空间的分配和释放。

      • 当分配的空间小于128 Bytes时,将使用第二级空间配置器。第二级空间配置器采用了内存池技术,通过空闲链表来管理内存,初始配置一大块内存,并维护对应不同内存空间大小的的16个空闲链表,它们管理的内存块大小是8、16、24、...、128 bytes,如果有内存需求,直接在空闲链表中取,如果有内存释放,则归还到空闲链表中。

       

      常用头文件

      C++标准库定义的无扩展名的头文件

      <iterator>

      <functional>

      <vector>

      <deque>

      <list>

      <queue>

      <stack>

      <set>

      <map>

      <algorithm>

      <numeric>

      <memory>

      <utility>

      <string>

      <unordered_set>

      <unordered_map>

      Mac上的源码路径:

      /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/

       

      容器与数据结构

      下图为常见数据结构,下面会结合数据结构讲解容器的实现原理。

       

  2. 序列式容器

    序列式容器:以线性排列来存储某一指定类型的数据,对应于数据结构中的线性表。

    2.1 数组类容器

    2.1.1 vector

    vector可以看做是支持模板的动态数组容器,它满足数组内存连续存储,O(1)遍历,O(n)插入删除的特性,并且可以动态扩缩容。

    vector的实现

    LLVM版本vector实现

    template <class _Tp, class _Allocator>
    class __vector_base
        : protected __vector_base_common<true>
    {
    public:
        typedef _Allocator                               allocator_type;
        typedef allocator_traits<allocator_type>         __alloc_traits;
        typedef typename __alloc_traits::size_type       size_type;
    protected:
        typedef _Tp                                      value_type;
        typedef value_type&                              reference;
        typedef const value_type&                        const_reference;
        typedef typename __alloc_traits::difference_type difference_type;
        typedef typename __alloc_traits::pointer         pointer;
        typedef typename __alloc_traits::const_pointer   const_pointer;
        typedef pointer                                  iterator;
        typedef const_pointer                            const_iterator;
    
        pointer                                         __begin_;
        pointer                                         __end_;
        __compressed_pair<pointer, allocator_type> __end_cap_;
    };

     

    vector的遍历

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    int main()
    {
        vector<int> values{1,2,3,4,5};
        //1.下标遍历
        for (int i = 0; i < values.size(); i++) {
            cout << values[i] << " ";
        }
        cout << endl;
        //2.迭代器遍历
        for (vector<int>::iterator pos = values.begin(); pos != values.end(); ++pos) {
            cout << *pos << " ";
        }
        cout << endl;    
        //3.range for (c++11)
        for (const auto& value : values) {
            cout << value << " ";    
        }
        cout << endl;
        //4. for_each (c++11)
        for_each(values.begin(), values.end (), [&](int v){ cout <<v <<" ";});
        cout << endl;
        return 0;
    }

    vector元素删除

    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int main()
    {
        std::vector<int> demo{ 1,3,5,4,3,2,5,2,1 };
        //1.使用迭代器删除3
        for(auto iter = demo.begin(); iter != demo.end();) {
        	if(*iter = 3){
          	iter = demo.erase(iter);
          }else{
          	iter++;
          }
        }
        for (const auto& value : demo) {
            cout << value << " ";    
        }    
        cout << endl;
        cout << "size is :" << demo.size() << endl;
        cout << "capacity is :" << demo.capacity() << endl;
        //2.使用remove函数交换要删除元素和最后一个元素的位置
        auto iter = std::remove(demo.begin(), demo.end(), 3);
        cout << "size is :" << demo.size() << endl;
        cout << "capacity is :" << demo.capacity() << endl;
        //输出剩余的元素
        for (auto first = demo.begin(); first != iter;++first) {
            cout << *first << " ";
        }
        return 0;
    }

    vector的初始化

    初始化

    std::vector<char>value1(5, 'c');
    std::vector<char>value2(value1);
    int array[]={1,2,3};
    std::vector<int>values(array, array+2);//values 将保存{1,2}
    std::vector<int>value3{1,2,3,4,5};
    std::vector<int>value4(std::begin(value3),std::begin(value4)+3);//value3保存{1,2,3}

    赋值

    std::vector users;
    //预分配内存,防止频繁动态扩容造成性能损耗
    //1.reserve
    users.reserve(1000);
    for (int i = 0; i < 1000; ++i)
     users.pus
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值