容器适配器

mac2024-05-27  42

每种容器都提供了一组接口,如果容器中的接口不能满足需求 ,那么应该重新编写容器还是改变我们的需求?根据转接线的例子可知,既不需要重新编写容器也不需要修改需求,而是应该构造一个容器接口到需求接口之间的转换器,称为容器适配器。

**容器适配器将原容器进行了一层封装,底层基于普通容器,上层对外提供封装后的新接口,满足不同使用者的需求。**容器适配器对使用者是个黑盒。除了使用STL提供的容器适配器,也可以构造自己的容器适配器,将STL中的容器进行封装,对外提供所需的接口。

容器适配器可以封装的容器类型,根据容器适配器对外提供的接口和容器适配器的内部算法而定。但是任何容器适配器对底层容器都有一些通用的要求,因此array不能作为容器适配器的底层容器。容器适配器和底层容器是组合的关系,插入容器适配器中的元素最终都保存在容器中,容器适配器中的数据成员包括一个用于存储元素的底层容器对象和一些辅助数据。

STL中的容器适配器

**栈适配器:**栈的特征是后进先出,后入栈的元素先出栈,先入栈的元素后出栈,因此栈适配器应该支持从栈顶添加删除元素以及访问栈顶元素的操作。容器vector,list和deque都满足栈操作的条件,因此都能作为栈适配器的底层容器,STL中默认使用deque作为栈适配器的底层容器。

**队列适配器:**队列的特征是先进先出,先入队的元素先出队,后入队的元素后出队,因此队列适配器应该支持从队头删除元素、向队尾添加元素以及访问队头队尾元素的操作。由于容器vector在删除首元素时需要移动所有元素,因此不适合作为队列适配器的底层容器,应该选用list或者deque,STL中默认使用deque作为队列适配器的底层容器。

优先队列在逻辑上与队列相似,一端插入元素另一端删除元素,但是优先队列在元素中加入了权重的概念。优先队列中的元素并非像队列一样按照插入的顺序依次排列,而是**根据元素的权重排列。添加元素时按照元素优先级插入到相应的位置,删除元素时将优先级最高的元素删除。**优先队列中,权重相邻的元素在底层容器中并不相邻。实际上优先队列利用底层容器实现了一个堆,堆顶的元素优先级最高。堆背后的数据结构是一个二叉树,底层容器中的元素就是二叉树中的结点,二叉树通过顺序容器的下标存储父子结点之间的关系。它的插入删除元素在底层容器实现的堆上进行操作,在堆的插入删除算法中,需要随机访问元素,所以STL中默认使用vector作为优先队列适配器的底层容器。

栈: stack<int> s1; //默认使用deque stack<int,vector<int>> s2; //默认使用vector 队列: queue<int> q1; //默认使用deque queue<int,list<int>> q2; //默认使用list 优先队列: priority_queue<int> p1; //默认使用vector priority_queue<int,deque<int>> p2; //默认使用deque priority_queue<int,vector<int>,cmp>> p3; //指定使用vector和权重比较函数cmp 栈适配器支持删除栈顶元素pop,向栈顶压入元素push,返回栈顶元素top; 队列适配器支持删除队首元素pop,向队尾添加元素push,返回队首元素front,返回队尾元素back; 优先队列适配器支持删除最高优先级元素pop,添加元素push,返回最高优先级元素top。
最新回复(0)