目录
1.stack与queue
stack
queue
2.priority_queue
2.1相关介绍
2.2模拟实现priority_queue
--仿函数:
--push
--pop
--top
--size
--empty
--迭代器区间构造
2.3仿函数
3.容器适配器
stack模拟实现
queue模拟实现
学习目标:
1.stack和queue介绍与使用
2.priority_queue的介绍和使用
3.容器适配器
1.stack与queue
stack
queue
stack与queue比较
- stack:只能尾插尾删,提供top(栈顶)
- queue:只能头删尾插,提供front,back
list与vector比较
- list:
- 插入删除效率高,提供了push_back,pop_back,push_front,pop_front
- 不支持随机访问,只有front,back
- vector:
- 头插头删效率低,提供了:push_back,pop_back
- 支持随机访问,提供了[],front,back
2.priority_queue
2.1相关介绍
1.优先级队列是一种容器适配器,它的第一个元素总是它包含元素的中最大的
2.与堆类似
3.接口功能与queue基本相同,其pop相当于弹出堆顶元素
4.其参数:
使用仿函数来决定是建立大堆或小堆
1.默认情况下priority_queue是大堆, 若要建立小堆:将第三个模板参数换位greater
priority_queue<int, vector<int>, greater<int>> q;
2.如果在priority_queue中放自定义类型的数据,用户需要在自定义类型中提供> 或者< 的重载
2.2模拟实现priority_queue
思路:
1.选择vector容器
2.priority_queue与堆类似,相当于完全二叉树
--插入数据: 1.在尾部插入数据2.开始向上调整
--删除数据: 1.将堆顶元素与尾部元素交换 2.从堆顶开始向下调整
3.使用仿函数来改变大小堆的建立
--仿函数:
template<class T>struct less {bool operator()(const T& left, const T& right){return left < right;}};template<class T>struct greater{bool operator()(const T& left, const T& right){return left > right;}};
--push
void push(const T& x) {//1.在尾部插入元素_con.push_back(x); //2.向上调整(从尾部)addjust_up(size()-1);}void addjust_up(size_t child) {Cmp cmp;size_t parent = (child - 1) / 2;while (child > 0) {//孩子比父节点大,交换/*if (_con[child] > _con[parent]) */if (cmp(_con[parent] , _con[child])){swap(_con[child],_con[parent]);child = parent;parent = (child - 1) / 2;}//否则直接结束else{break;}}}
--pop
void pop() {if (empty())return;//1.交换堆顶与尾部元素swap(_con[0],_con[size()-1]);_con.pop_back();//2.向下调整(从根)addjust_down(0);}void addjust_down(size_t parent) {Cmp cmp;size_t child = parent * 2 + 1;//2.向下调整while (child < size()) {//1.找到孩子节点较大的一个/*if (child + 1 < size() - 1 && _con[child + 1] > _con[child]) */if (child + 1 < size() - 1 && cmp(_con[child], _con[child + 1])){++child;}/*if (_con[child] > _con[parent]) */if (cmp(_con[parent], _con[child])){swap(_con[child],_con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}
--top
//堆顶元素不可修改,改了会改变堆的性质const T& top() {return _con.front();}
--size
size_t size() {return _con.size();}
--empty
bool empty() {return _con.empty();}
--迭代器区间构造
//迭代器区间构造template<class iterator>priority_queue(iterator first,iterator last) :_con(first,last){//从队列中第一个非叶子节点开始向下调整for (int num = ((size() - 1) - 1) / 2; num >= 0; num--) {addjust_down(num);}}
效果展示:
2.3仿函数
仿函数:通常指的是可以像函数一样调用的对象
仿函数是一个类或对象,它实现函数调用运算符operate(),使你可以像调用普通函数一样使用仿函数来执行一些操作
与C语言中的回调函数功能类似,回调函数作为参数传递给另一个函数,并且可以在后者执行过程中被调用, 其通常作为函数指针或函数引用的形式
示例:
template<class T> struct Less {bool operator()(const T& left, const T& right){return left < right;} };void test1() {Less<int> cmp;cout << cmp(1, 2) << endl; }
效果:
3.容器适配器
1.适配器定义:适配器是一种模式,该模式把类的接口转换为用户期望的另一个接口
stack和queue被成为容器适配器:这是因为stack和queue只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque
stack模拟实现
template<class T,class Container = deque<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();}const size_t size() {return _con.size();}bool empty() {return _con.empty();}private:Container _con;};
queue模拟实现
template<class T , class container = deque<T>>class Queue {public://构造函数Queue() {}void push(const T& x) {_con.push_back(x);}void pop() {_con.pop_front();}T& back(){return _con.back();}const T& back()const{return _con.back();}const T& front()const{return _con.front();}size_t size() const{return _con.size();}bool empty(){return _con.empty();}private:container _con;};