C++11——序列式容器总结

目录

         容器:

vector ——顺序表。

list ——环状双向链表

deque——双开口数组

容器适配器:

stack——先进后出

queue——先进先出

heap——堆(隐式表达) #include<aglorithm>

priority_queue——优先队列

标准之外:

slist——单链表


vector ——顺序表。

概述:vector类似于array,但vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。

迭代器:vector的迭代器是Random Access Iterators,vector迭代器就是普通指针(typedef value_type * iterator)

扩容:当vector扩容时,会发生“重新配置(两倍大小),元素移动,释放空间”等过程。删除时容量不变。

元素操作:对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就会失效。

STL标准规范中指出:插入时,新节点将位于哨兵迭代器的所指节点的前方。

list ——环状双向链表

list的迭代器:双向迭代器,插入和结合不会造成原有的list迭代器失效。删除时只有“指向被删除元素”的迭代器失效。

list的元素操作:remove(const T& value) :移除所有数值为value的元素。

                          unique() :移除数值连续相同的连续元素,只有连续相同的元素才会被移除,剩下一个。

                         splice(iterator position,list&x):将x链表接合与position所指位置之前。x必须不同于*this。

                          transfer(iterator position,iterator first,iterator last):将[first,last)内的元素移动到position之前。(非公开接口)

                          merge(list& x ):将x合并到*this身上。两个list的内容必须先经过递增排序。

                         sort():list不能使用STL算法中的sort(),必须使用sort()成员函数。STL算法中的sort()要求随机访问迭代器。

关于sort函数的解析:https://blog.csdn.net/shoulinjun/article/details/19501811 (STL剖析上写得快排,实际上应该是归并排序)

#include<iostream>
#include<list>
using namespace std;
int main()
{
	list<int> L = {1,2,2,2,3,4,4,3};
	L.unique();
	for (auto iter = L.begin(); iter != L.end(); iter++)
		cout << *iter << "  ";
	cout << endl;    //输出 1 2 3 4 3;
	L.remove(3);
	for (auto iter = L.begin(); iter != L.end(); iter++)
		cout << *iter << "   ";
	cout << endl;    //输出 1 2 4;

        list<int> iList = { 5,6,7,8 };
	auto iterPos = find(L.begin(), L.end(), 2);
	L.splice(iterPos, iList);
	for (auto iter = L.begin(); iter != L.end(); iter++)
		cout << *iter << "   ";     //输出1 5 6 7 8 2 4;
	cout << endl;	

	return 0;
}

deque——双开口数组

概述:deque是一种双开口的连续性线性空间。是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

中控器:deque用一块连续的map(非STL中的map容器)作为主控。map是一块连续的空间,其中每个元素都是指针,指向一段连续的线性空间,成为缓冲区。缓冲区才是deque的储存空间主体。SGI STL中默认缓冲区大小是512比特。

迭代器:Random Access Iterator,但是不是普通指针。

迭代器中包含:T* cur; 指向当前缓冲区的现行元素。

                         T* first;指向缓冲区的头。

                         T* last;指向缓冲区的尾。

                        map_pointer node;指向map中的特定的节点。

stack——先进后出

概述:栈是一种先进后出的数据结构,它只有一个出口。允许新增元素、移除元素、取得最顶端元素。

SGI STL中:stack以deque作为缺省情况下的stack底部结构。由于stack以底部容器完成其所有工作,从而具有adapter的“修改某物接口,形成另一种风貌”的性质,因此,STL stack 往往不归类为container(容器),而是归类为container adapter(容器适配器)。

stack:不允许遍历,也不提供迭代器。

list也是一种双向开口的数据结构,且list具有stack所有需要的底层容器的函数。所以list也可以作为stack的底层容器。

template<calss T,class Sequence = deque<T> >
class stack{
//friend function
//typedef 

protected: 
    Sequence c;
public:
    bool empty() const{return c.empty();}
    void pop(){ c.pop_back();}
    //...
};

stack<int,list<int>> iStack;

queue——先进先出

概述:queue是一种先进先出的数据结构,它有两个出口。queue允许从顶端移除元素、从底端加入元素、取得最顶端元素。

SGI STL中:queue以deque作为缺省情况下的queue底部结构。由于queue以底部容器完成其所有工作,从而具有adapter的“修改某物接口,形成另一种风貌”的性质,因此,STL queue往往不归类为container(容器),而是归类为container adapter(容器适配器)

queue:不允许遍历,没有迭代器。

可以以list作为queue的底层容器。

heap——堆(隐式表达)

概述:heap不是STL容器组件,是priority queue的助手。优先队列允许用户以任何次序将任何元素推入容器内,但取出时一定是从优先权最高(数值最高的)的元素开始取。binary max heap就具有这样的特性。

binary heap是一种完全二叉树,也就是说,整棵binary tree除了最底层的叶节点之外,是填满的,而最底层的叶节点由左至右不得有空隙。因此:我们可以利用array来存储所有的节点。用array表述tree的方式,称为隐式表达(implicit representation)。

按照元素排列方式,heap可以分为max-heap和min-heap两种。前者每个节点的键值都大于或等于其子节点的键值,后者每个节点的键值都小于或等于其子节点的键值。因此max-heap的最大值在根节点,min-heap的最小值在根节点。STL中所提供的是max -heap。   

heap算法:(在头文件<algorithm>中)

  • push_heap算法: 执行一个上溯程序:将新节点的值和其父节点比较,如果键值比父节点大,就父子交换位置,如此一直上溯,直到不需要交换或直到根节点为止。
  • pop_heap算法:将根节点取走,放入最下层最右边的叶节点,然后执行一个下溯程序(_adjust_heap):将新节点的值和其孩子节点比较,如果 键值比孩子节点的小,将其和较大的孩子节点对调,如此一直下溯,直至不需要交换或者到了叶子节点为止。
  • sort_heap算法:持续对整个heap做pop_heap操作,每次将操作范围从后向前缩减一个元素。
  • make_heap算法: 从n/2的节点开始执行下溯程序 直到节点0;

priority_queue——优先队列

priority_queue:拥有权值观念的queue。权值最高值排在最前面。缺省情况下以vector为底层容器,利用max-heap完成。是container adapter。没有迭代器。

template<class T,class Sequence = vector<T>,
        class Compare = less<typename Sequence::value_type> >
class priority_queue
{
    public:
        //typedef
    protected:
        Sequence c;    //        底层容器
        Compare com;
    public:
        //member function

};

slist——单链表

SGI STL中提供单链表(single linked list),名为slist。它并不在标准规格内。

slist和list比较:

  • 差别:slist的迭代器是单向的,list的迭代器的双向的,slist对的功能是受限的。但是slist所消耗的空间更小,某些操作更快。
  • 相同:它们的insert、erase、splice等操作不会造成原有迭代器的失效。(除被移除的当前迭代器)

slist:是一个带头结点的链表。“头结点”位于链表的第一个元素之前,它的data域可以不存储任何信息。

                                                                                                                                                                                                                                                                                                                                                                        

看源码的时候产生的疑问:

1. uninitialized_fill 和 fill 的区别:

    uninitialized_fill(未初始化填充) 是要根据value的类型来判断使用哪一种方式填充,uninitialized_fill一般都是用于未初化填充,也就是说内存区间根本没有对象可言.

    fill是直接对每个元素进行填充value.如果是POD类型(就是内置类型或普通结构与类(没有指针的成员数据)),就直接调用fill函数.不是POD类型时,就要遍历每个元素进行构造(调用construct函数).那是因为*first = value; 类的赋值操作符必须要*first的对象已经生成.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值