stack、queue和priority_queue(容器适配器、仿函数的使用)
1.stack的使用
函数说明 | 接口说明 |
stack() | 构造空的栈 |
empty() | 检测stack是否为空 |
size() | 返回stack中元素的个数 |
top() | 返回栈顶元素的引用 |
push() | 将元素val压入stack中 |
pop() | 将stack中尾部的元素弹出 |
2.模拟实现stack
在模拟实现stack的过程中,我们只需要封装一个其他容器就可以实现,这里就需要容器适配器,用已经有的容器去实现stack需要的接口,就完成stack。
#include<vector>
#include<list>#include<iostream>using namespace std;namespace zyf
{template<class T, class container = vector<T>>class stack{public:stack(){}void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}const T& top(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:container _con;};}3.queue的使用
函数声明 | 接口说明 |
queue() | 构造空的队列 |
empty() | 检测队列是否为空,是返回true,否则返回false |
size() | 返回队列中有效元素的个数 |
front() | 返回队头元素的引用 |
back() | 返回队尾元素的引用 |
push() | 在队尾将元素val入队列 |
pop() | 将队头元素出队列 |
4.queue的模拟实现
#include<vector>
#include<list>#include<iostream>using namespace std;namespace zyf
{template<class T, class container = list<T>>class queue{public:queue(){}void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}const T& front(){return _con.front();}const T& back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:container _con;};}5. priority_queue的使用
优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中
元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用
priority_queue。注意:默认情况下priority_queue是大堆。
函数声明 | 接口说明 |
priority_queue()/priority_queue(first, last) | 构造一个空的优先级队列 |
empty( ) | 检测优先级队列是否为空,是返回true,否则返回false |
top( ) | 返回优先级队列中最大(最小元素),即堆顶元素 |
push(x) | 在优先级队列中插入元素x |
pop() | 删除优先级队列中最大(最小)元素,即堆顶元素 |
6. priority_queue的实现
#pragma once
#include<iostream>
using namespace std;
#include<vector>
namespace zyf
{template<class T>class less{public:bool operator()(const T& x, const T& y){return x < y;}private:};template<class T>class great{public:bool operator()(const T& x, const T& y){return x > y;}private:};template<class T, class container = vector<T>, class comp = less<T>>class priority_queue{public:void AdjustUp(size_t child){comp ch;size_t parent = (child - 1) / 2;while (child > 0){if (ch(_con[parent],_con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){_con.push_back(x);AdjustUp(_con.size() - 1);}void AdjustDown(int parent){comp ch;int child = 2 * parent + 1;while (child < _con.size()){if (child+1 < _con.size()&&ch(_con[child], _con[child + 1])){child++;}if (ch(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = 2 * parent + 1;}else{break;}}}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown(0);}size_t size(){return _con.size();}bool empty(){return _con.empty();}int top(){return _con[0];}private:container _con;};}过程中包含了仿函数的使用,仿函数本质上是一个对operator()的重载。
