一、适配器
适配器是标准库中的一个通用概念。容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一件事物一样。一个容器适配器接收一种已有的容器类型,使其行为看起来像一种不同的类型。例如:stack适配器接受一种顺序容器(除array或forward_list外),并使其操作看起来像一个stack一样。
二、容器适配器的定义
以deque<int>初始化stack为例:
方式一:
//默认参数类型 stack在不指定适配容器类型的话,默认使用deque来适配
deque<int> deq;
stack<int> stk(deq); //从deq拷贝元素到stk
方式二:
stack<int , deque<int>> stk; //空栈
stack<int , deque<int>> stk(deq) // 拿deq来初始化stk;
三、栈适配器(stack)
后进先出(LIFO,las-in first-out),只从容器的一端插入和删除元素。插入和删除端被称为stack的顶部(top)。
stack适合的顺序容器类型有:vector, deque , list 。如果没有顺序容器来对stack进行初始化,则使用默认标准容器类型:deque。
容器模板参数:
1.T 元素的类型,stack::value_type
2.Container 适配容器类型,stack::container_type
类型:
member type | definition | notes |
---|---|---|
value_type | The first template parameter (T) | Type of the elements |
container_type | The second template parameter (Container) | Type of the underlying container |
reference | container_type::reference | usually, value_type& |
const_reference | container_type::const_reference | usually, const value_type& |
size_type | an unsigned integral type | usually, the same as size_t |
成员函数:
empty //判断容器是否为空
size //查看容器大小
top //访问栈顶元素
push //插入元素
emplace //访问并插入元素
pop //弹出栈顶元素
swap //交换两个容器当中的元素
实例:
#include <iostream>
#include <stack>
#include <list>
#include <deque>
#include <vector>
using namespace std;
void main()
{
//默认构造类型
deque<int> deq = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
stack<int> stk(deq); // 默认构造类型,stack在不指定适配容器类型时,默认使用deque来进行适配
cout << "stk : ";
while (!stk.empty()) //empty函数,用于判断stack是否为空
{
cout << stk.top() << ends; //访问栈顶元素 返回对应的元素类型
//循环打印出来的结果是:9 8 7 6 5 4 3 2 1
stk.pop(); //void类型,弹出元素
}
cout << endl;
//使用一个容器来初始化stack
vector<int> vct = { 1,2,3,4,5,6,7,8,9 };
stack<int, vector<int>> stk_1; //空实现
stack<int, vector<int>> stk_2(vct); //使用户vct去初始化stk;
cout << "stk_1 : ";
stk_1.swap(stk_2); //swap函数
while (!stk_1.empty())
{
cout << stk_1.top() << ends;
stk_1.pop();
}
cout << endl;
//-------------------------------------------
list<int> lst = { 1,2,3,4,5,6,7,8,9 };
stack<int, list<int>> stk_3(lst);
stack<int, list<int>> stk_4;
stk_4.swap(stk_3);
for (int i = 0; i < 5; i++)
stk_3.push(i * 10);
cout << "stk_3 before emplace() : ";
while (!stk_3.empty())
{
cout << stk_3.top() << ends;
stk_3.pop();
}
cout << endl;
stk_4.emplace(100); //在栈顶插入元素,和push功能差不多
cout << "stk_4 after emplace() : ";
while (!stk_4.empty())
{
cout << stk_4.top() << ends;
stk_4.pop();
}
}
四、队列适配器(queue)
先进先出(FIFO,first-in firs-out),元素从容器的一端进入,从另一端出来。
queue可以适配的顺序容器有:deque 和 list 。vector不适合queue适配器,因为vector只能在单端操作。在没有对queue进行容器初始化时,默认适配的标准容器为deque
模板参数:
1. T : 元素的类型queue::value_type
2. Container : 适配容器类型 : queue::container_type
类型:
member type | definition | notes |
---|---|---|
value_type | The first template parameter (T) | Type of the elements |
container_type | The second template parameter (Container) | Type of the underlying container |
reference | container_type::reference | usually, value_type& |
const_reference | container_type::const_reference | usually, const value_type& |
size_type | an unsigned integral type | usually, the same as size_t |
成员函数:
empty //
size //
swap //
front //访问队首元素
back //访问对位元素
push //从对尾插入元素
pop //从队首弹出元素
emplace //Construct and insert element
实例:
#include <queue>
#include <list>
#include <deque>
#include <iostream>
using namespace std;
void main()
{
queue<int> que; //queue的默认构造类型,在没有初始化容器类型时,默认为deque类型,此处用dq初始化que
for (int i = 1; i < 10; i++)
que.push(i);
cout << "que.size : " << que.size() << endl;
cout << "que.front : " << que.front() << endl;
cout << "que.back : " << que.back() << endl;
cout << "que : ";
while (!que.empty())
{
cout << que.front() << ends; //对队首元素一个一个遍历
que.pop(); //弹出的是队首元素
}
cout << endl;
//-------------------------------------
list<int> ls = { 1,2,3,4,5,6,7,8,9 };
queue<int, list<int>> que_ls1(ls);
queue<int, list<int>> que_ls2;
for (int i = 0; i < 10; i++)
que_ls2.push(i * 10);
que_ls1.swap(que_ls2);
//que_ls1 : 0,10,20,30,40,50,60,70,80,90
//que_ls2 : 1,2,3,4,5,6,7,8,9
que_ls1.emplace(10000);
que_ls2.emplace(10000); //和push的功能差不多
cout << "que_ls1 : ";
while (!que_ls1.empty())
{
cout << que_ls1 .front() << ends; //对队首元素一个一个遍历
que_ls1.pop(); //弹出的是队首元素
}
cout << endl;
cout << "que_ls2 : ";
while (!que_ls2.empty())
{
cout << que_ls2.front() << ends; //对队首元素一个一个遍历
que_ls2.pop(); //弹出的是队首元素
}
cout << endl;
}
五、优先级队列适配器(priority_queue)
优先级队列的第一个元素一般都是容器中最大的元素,其结构和堆(heap)比较相似,同一类型的元素可以随意插人,插入后会进行大小比较,最大的元素会被放于最前面(也就是队顶(top)元素)。
优先级 队列插入元素的位置是根据元素的大小来进行判断的,删除(弹出)元素在优先级队列的队顶(top)。
优先级队列适配器初始化容器类型一般是:vector , deque 。如果在定义中没有初始化容器类型,则默认为vector类型。
模板参数:
1. T : 元素类型:priority_queue::value_type
2. Container : 容器类型: priority_queue::container_type
3. Compare : 看是按照从小到大排列还是从大到小排列。
类型:
member type | definition | notes |
---|---|---|
value_type | The first template parameter (T) | Type of the elements |
container_type | The second template parameter (Container) | Type of the underlying container |
reference | container_type::reference | usually, value_type& |
const_reference | container_type::const_reference | usually, const value_type& |
size_type | an unsigned integral type | usually, the same as size_t |
成员函数:
empty //
size //
top //获取队顶(top)元素,一般为最大或最小元素
push //插入元素
pop //移除队顶(top)元素
swap //
emplace
实例:
#include <iostream>
#include <functional>
#include <queue>
#include <deque>
#include <vector>
using namespace std;
void main()
{
priority_queue<int,vector<int>> prique;
prique.push(132);
prique.push(46);
prique.push(32);
prique.push(1);
prique.push(21000);
prique.push(3200);
prique.emplace(10); //和push的功能差不多
cout << "max element : " << prique.top() << endl;
prique.emplace(100000);
cout << "max element : " << prique.top() << endl;
while (!prique.empty())
{
cout << prique.top() << ends;
prique.pop();
}
cout << endl;
//------------------------------------------
priority_queue<int, vector<int>, greater<int> > prique1; //greater<int> 在#include <functional>这个头文件中
prique1.push(132);
prique1.push(46);
prique1.push(32);
prique1.push(1);
prique1.push(21000);
prique1.push(3200);
prique1.emplace(10); //和push的功能差不多
cout << "min element : " << prique1.top() << endl;
prique1.emplace(100000);
cout << "min element : " << prique1.top() << endl;
while (!prique1.empty())
{
cout << prique1.top() << ends;
prique1.pop();
}
}