STL-配置器(stack,queue,deque,list)

配置器


  • 00.list
  1. list是一种双向开口的非连续性的结构,它的每个元素都是一个独立的节点,互不影响,只是用其节点的结构将其进行连接,其就是一个双向链表
  2. list的迭代器就是一个节点,这个节点就是链表中某个节点的指针。
  3. 迭代器的operator *( )就是这个节点中存储的数据,operator++( )就是
    向后移动一个节点,operator就是向前移动一个节点。
    这里写图片描述
    这里写图片描述
  4. 其实list不仅仅是一个双向链表,它是一个带头带环的双向链表。
    这里写图片描述

  • 01.deque空间

1.deque是一种双向开口的连续线性空间,所谓双向开口是指,其可以在容器的两端进行操作。
2.相比vector在头部插入效率的低下,所以deque要比vector效率高了不少。
3.deque其实只是理论上的连续空间,分装后用户感知不到其内部实现,但用法和vector相似,所以被认为是连续空间。
4.deque只是将一小段一下段连续空间及逆行组合而成,随时可以加入一段新的连续空间,这样就没有所谓的扩容了,容量理论上是无限大的。

  • 02.deque的中控器
  1. 可以想象deque都是一段一段的连续空间,想要对这些零散的小段的连续空间进行管理,要不vector要难上许多。
  2. 为了维持表面的连续空间的假象,这是就用到了deque的中控器map,但是这个map和STL的map没有任何关系。
  3. map其实就是将这些散开的空间进行有效的组织使其继续维持表面的假象。这也使迭代器的实现变得要比vector的要复杂很多。
    这里写图片描述
    用一张更加复杂的图来说在感受下
    这里写图片描述

    a.中控器上的每个节点node都是指向了存储空间的真实位置,而node指向的这段稍微大点的连续空间才是deque真实存储的数据的空间。这里可以类比Linux下的文件系统,每个inode节点都是保存了其真实存储数据的节点编号,按照inode里面编号,就可以在后面的数据块中进行索引。


    b.可以从图中看到,一个deque的迭代器是多么复杂,相比vector的一个原生指针是复杂了不少的,也由此可以看出deque的维护其实要不vector复杂很多的。


    c.一个deque的迭代器,包含了其对应一个指向中控器map的节点,一个指向小段连续空间的头,一个指向小段连续空间的尾,和一个指向当前在这个小段连续空间中访问到哪个元素的位置。

  • 03.stack
  1. stack是一种后进先出的数据结构,它只有一个出口。
  2. stack的所有操作都是在一端进行操作的,我们称之为栈顶。
  3. 这也决定了stack并不支持所谓的迭代工作,因为自生结构的属性决定了其只能在栈顶进行操作,所以只能从结构中拿一个遍历一个。
  4. 为什么要和stack一个写成一篇博客呢?主要是因为STL中stack不叫容器,而是配接器,或者称为适配器。因为在STL中它不是自己原生的数据结构,而是在别的容器上,封装的结构。
  5. stack的适配的容器有两个即deque和list。
//用deque进行配置stack
template<class T,class Sequence = std::deque<T> >
class Stack
{
public:
    size_t Size(){return s.size();}
    bool Empty(){return s.empty();}
    T& Top(){return s.back();}
    void Push(){s.push_back();}
    void Pop(){s.pop_back();}

protected:
    Sequence s;
};

//下面用list进行配置stack
template<class T, class Sequence = std::list<T> >
class Stack
{
public:

    size_t Size(){return s.size();}
    bool Empty(){return s.empty();}
    T& Top(){return s.back();}
    void Push(){s.push_back();}
    void Pop(){s.pop_back();}

protected:
    Sequence s;
};
  • 04.queue
  1. queue是一种先进先出的结构,同stack一样,他也只有一个开口。
  2. 同stack一样queue所有操作都只能在其一端进行操作,称之队头。
  3. 因为只能在一端进行操作,所以其也是不支持便利操作,只能从对头取一个,访问一个。
  4. queue的同样不是自己原生实现的结构,而是建立在别的容器之上,对其简单封装,就变成了queue。
    5.queue的配置同stack,都有deque和list
//下面用deque来配置queue
template<class T,class Sequence = std::deque<T> >
class Queue
{
public:
    size_t Size(){return s.size();}
    bool Empty(){return s.empty();}
    T& Front(){return s.front();}
    void Push(){s.push_front();}
    void Pop(){s.pop_front();}
protected:
    Sequence s;
};


//下面用list来配置queue
template<class T,class Sequence = std::list<T> >
class Queue
{
public:
    size_t Size(){return s.size();}
    bool Empty(){return s.empty();}
    T& Front(){return s.front();}
    void Push(){s.push_front();}
    void Pop(){s.pop_front();}
protected:
    Sequence s;
};

以上参考STL源码剖析,如有错误,可以私信我,这里表示感谢!

猜你喜欢

转载自blog.csdn.net/SkinWhite/article/details/81448458
今日推荐