【STL】容器适配器

一、适配器

适配器是标准库中的一个通用概念。容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一件事物一样。一个容器适配器接收一种已有的容器类型,使其行为看起来像一种不同的类型。例如: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();
	}

}

 

展开阅读全文

没有更多推荐了,返回首页