STL之序列式容器

本文介绍了STL中的序列式容器,包括vector、list和deque。vector是一个线性连续空间,支持尾部插入和删除;list是循环双向链表,其插入操作不会使迭代器失效;deque是双端队列,允许在两端进行快速插入和删除,其内部通过map结构管理不连续的存储空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STL大致分类:
(1)容器
序列式容器:vector(向量容器)、deque(双端队列)、list(双向列表)
关联式容器:集合(set、multiset)、映射(map、multimap)
容器适配器:stack、queue、priority_queue
(2)迭代器
Input iterator、Output iterator、Forward iterator、Bidirectional iterator、Random iterator
(3)泛型算法
(4)仿函数(函数对象)
绑定器:bind1st、bind2nd
取反器:not1、not2
(5)空间配置器

这里先看一下,序列式容器@.@(推眼镜)
(1)、vector向量容器
vector的数据结构:线性连续空间

template<class T,class Alloc = alloc>
class vector
{
...
protected:
iterator start;    //表示目前使用空间的头
iterator finish;   //表示目前使用空间的尾
iterator end_of_storage;    //表示目前可用空间的尾
}

这里写图片描述
运用这三个迭代器可以轻便的提供首尾标识、首尾元素值、容量、大小、空容器判断、下标运算[ ]

template<class T,class Alloc = alloc>
class vector
{
    ...
    public:
    iterator begin() {return start;}
    iterator end() {return finish;}
    size_type size() const {return size_type(end()-begin());}
    size_type capacity() const {return size_type(end_of_storage-begin());}
    bool empty const{return begin() == end();}
    reference operator[](size_type n){return *(begin()+n);}
    reference front(return *begin();)
    reference back(return *end()-1;)
}

功能函数:
void push_back( const T& x); //尾插
void pop_back(); //取出尾端的元素
iterator erase(iterator position); //删除position处的元素
void resize( ) {size_type new_size}; //重置容器大小
void insert(iterator position,size_type n,const T& x);

2、list(循环双向链表)

template<class T>
struct _list_node
{
    typedef void* void_pointer;
    void_pointer prev;
    void_pointer next;
    T data;
}

这里写图片描述
list结点的结构
list的重要特性:插入insert操作和接合splice操作都不会导致原来的list迭代器失效,只有“指向被删除元素”的迭代器会失效。
list的数据结构:

template<class T,class Alloc = alloc>
struct list
{
protected:
    typedef _list_node<T> list_node;
public:
    typedef list_node* link_type;
protected:
    link_type node;  //只要一个指针,便可表示整个环状双向链表
}

list的设计精巧之处,也可以从这里看出,在链表尾端加上一个空白节点node,便能符合STL对于“前闭后开”区间的要求,成为last迭代器。
这个设计有多方便,从下面几个函数就可看出:

iterator begin() {return (link_type)((*node).next);}
iterator end() {return node;}
bool empty(){return node->next == node;}
size_type size() const
{
    size_type result = 0;
    distance(begin(),end(),result);
    return result;
}
reference front() {return *begin();}
reference back() {return *(--end());}

这里写图片描述
List示意图

 void push_back(const T& x){insert(end( ),x);}  //尾插
 void push_front (const T& x) {insert(begin(),x)}   //头插
 iterator erase(iterator position);   //删除
 void pop_front( ) { erase( begin( ) ); }
 void pop_back( ) {iterator tmp = end( ); erase(--tmp;) } 
 void remove(const T& value);    //将所有value元素都移除
 void unique( );      //移除连续的相同元素,最终剩一个
 void splice(iterator position,list &x);  //将x移到position所指位置之前
 void reverse( );    //链表逆置
 void merge(List<T,Alloc>T & x); //合并两个链表

3、deque(双端队列)
deque是双向开口的连续线性空间,既两端都能进行插入删除操作。
它的结构如下:
这里写图片描述
deque的空间增长直接申请更大的区域串接在头或者尾,所以deque需要在这些分段的连续空间上维护其整体连续的假象并提供随机存储,这样做导致了它复杂的迭代器架构。
deque设计了一个map(一块连续空间,里面存放指向各个分段空间的地址)结构,用于管理不连续的分段。

typedef value_type* pointer;
typedef pointer* map_pointer;
map_pointer map;

map为一个二级指针,指向一块连续的空间,这块空间里的每一个为元素都是一个指针,指向一块更大的存储空间(deque的存储主体)
结构如下:
这里写图片描述
正因为deque的特殊结构,所以给迭代器带来了不小的压力,对于++operator或者operator++的操作,涉及到跳级。

typedef T value_type;
T* cur;   //指向缓冲区的现行元素
T* first;   //指向缓冲区的头
T* last;     //指向缓冲区的尾
map_pointer node;    //同map一样,二级指针,指向map中的元素

map(中控器)、迭代器、缓冲区之间的关系图如下所示:
这里写图片描述
专门设有start和finish的迭代器
这里写图片描述
功能函数:

void push_back(const value_type& x);   //尾插
void push_front(const value_type& x);   //头插
void pop_back();    //取尾部元素
void pop_front();   //取头部元素
iterator erase(iterator position);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值