赞
踩
目录
容器适配器是一个封装了序列容器的一个类模板,它在一般的序列容器的基础上提供了一些不同的功能。之所以称为容器适配器,是因为它是适配容器来提供其它不一样的功能。通过对应的容器和成员函数来实现我们需要的功能。
下面介绍了三个容器适配器:statk<T>,queue<T>,priority_queue<T>。
注意:容器适配器都不存在迭代器。
函数名称 | 功能 |
stack() | 构造一个空栈 |
empty() | 判断栈是否为空,空返回true,非空返回false |
size() | 返回栈元素个数 |
top() | 返回栈顶元素的引用 |
push() | 在栈顶插入元素 |
pop() | 将stack栈顶元素弹出 |
使用stack需要包含头文件#include<stack>,stack不存在迭代器。
- #include<iostream>
- #include<deque>
- #include<vector>
- #include<list>
- using namespace std;
-
- namespace my{
- template<class T,class Container=deque<T>>
-
- class stack{
- public:
- bool empty(){
- return _con.empty();
- }
- size_t size(){
- return _con.size();
- }
- T& top(){
- return _con.back();
- }
- const T& top()const{
- return back();
- }
- void push(const T& val){
- _con.push_back(val);
-
- }
- void pop(){
- _con.pop_back();
- }
- private:
- Container _con;
-
- };
-
- void test_stack(){
- stack<int> s;
-
- s.push(1);
- s.push(2);
- s.push(3);
- s.push(4);
-
- while (!s.empty())
- {
- cout << s.top() << " ";
- s.pop();
- }
- cout << endl;
- }
-
- void test_stack1(){
- stack<int,list<int>> s;
-
- s.push(1);
- s.push(2);
- s.push(3);
- s.push(4);
-
- while (!s.empty())
- {
- cout << s.top() << " ";
- s.pop();
- }
- cout << endl;
- }
- }
函数声明 | 功能介绍 |
queue() | 构造空队列 |
size() | 返回队列中的元素个数 |
empty() | 判断队列是否为空 |
back() | 返回队尾元素引用 |
front() | 返回队头元素引用 |
push() | 在对尾插入元素 |
pop() | 将队头元素弹出 |
使用queue需要包含头文件#include<queue>,queue容器适配器没有迭代器
因为queue存在头删和尾插,因此使用vector容器来封装效率太低,头删需要挪动数据,并且vector并没有提供pop_front(),因为效率太低。
- #pragma once
- #include<iostream>
- #include<deque>
- #include<vector>
- #include<list>
- using namespace std;
-
- namespace my{
- template<class T, class Container = deque<T>>
- class queue{
- public:
- //会调用容器构造函数
- queue(){};
- //注意有隐含this指针
- size_t size()const{
- return _con.size();
- }
- bool empty()const{
- return _con.empty();
- }
- T& back(){
- return _con.back();
- }
- T& front(){
- return _con.front();
- }
- const T& back()const{
- return _con.back();
- }
- const T& front()const{
- return _con.front();
- }
- void push(const T& val){
- _con.push_back(val);
- }
- void pop()
- {
- _con.pop_front();
- }
- private:
- Container _con;
- };
-
- void test_queue1(){
- queue<int> q;
- q.push(1);
- q.push(2);
- q.push(3);
- q.push(4);
-
- cout << q.size() << endl;
- cout << q.back() << endl;
- cout << q.front() << endl;
-
- while (!q.empty()){
- cout << q.front() << " ";
- q.pop();
- }
- cout << endl;
-
- }
- }
简单介绍一下仿函数:
仿函数(Functor)又称为函数对象(Function Object)是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载 operator() 运算符。因为调用仿函数,实际上就是通过类对象调用重载后的 operator() 运算符。仿函数是一个类,只是使用起来像函数。等下模拟实现时就知道了。
优先队列默认使用vector作为存储数据的容器,在容器的基础上使用堆算法,将vector中的元素调整成一个堆结构。
注意:优先队列就是一个堆,在使用堆的地方都可以使用优先队列。默认生成大根堆,头文件也是#include<queue>
函数 | 功能 |
priority_queue() | 建立一个空优先队列 |
priority_queue(first,last) | 将迭代器first到last之间的元素建堆 |
top | 返回优先级队列中优先级最高元素,即堆顶元素 |
size | 返回优先队列里的元素个数 |
empty | 判断优先队列是否为空 |
push | 往优先队列中插入元素 |
pop | 删除优先级队列中优先级最高元素,即堆顶元素 |
注意:如果在priority_queue中放自定义类型的数据,即在存储数据的容器中放自定义类型数据需要将操作符<和>重载,因为要进行调整称堆。
回顾一下堆的插入与删除操作。
堆的插入:在堆尾插入数据,再向上调整成堆。
堆的删除:将堆顶元素和对尾元素交换,再向下调整成堆。
不带仿函数:
调整函数:
- #pragma once
- #include<iostream>
- #include<deque>
- #include<vector>
- #include<list>
- using namespace std;
-
- namespace my{
- template<class T,class Container = vector<T>>
- class priority_queue{
- public:
- priority_queue(){};
- template<class inputiterator>
- priority_queue(inputiterator first, inputiterator last){
- while (first != last){
- push(*first);
- first++;
- }
- }
- bool empty(){
- return _con.empty();
- }
- size_t size(){
- return _con.size();
- }
- T& top(){
- return _con.front();
- }
- const T& top()const{
- return _con.front();
- }
- void push(const T& val){
- _con.push_back(val);
- Adjustup(_con.size() - 1);
- }
- void pop(){
- swap(_con[0], _con[_con.size() - 1]);
- //少一个元素是size减减,交换后,直接删除最后一个元素
- _con.pop_back();
- Adjustdown(0);
- }
- private:
- void Adjustup(int child){
- int parent = (child - 1) / 2;
- while (child > 0){
- if (_con[child] > _con[parent]){
- swap(_con[child], _con[parent]);
- child = parent;
- parent = (child - 1) / 2;
- }
- else{
- break;
- }
- }
- }
-
- void Adjustdown(int parent){
- int child = parent * 2 + 1;
- //不能减1,如果没有元素size()为0,类型size_t,减1就是最大的数(正数),会进入循环
- while ((size_t)child < _con. size() ){
- if (child + 1 < _con.size() && _con[child + 1] > _con[child]){
- child++;
- }
- if (_con[child]>_con[parent]){
- swap(_con[child], _con[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else{
- break;
- }
- }
- }
-
- Container _con;
- };
-
- void test_priority_queue(){
- int array[] = { 8, 4, 6, 2, 10 };
- priority_queue<int> pq(array, array + sizeof(array) / sizeof(int));
- cout << pq.size() << endl;
-
- while (!pq.empty()){
- cout << pq.top() << " ";
- pq.pop();
- }
- cout << endl;
-
- }
- }
仿函数:优先队列通过仿函数来实现建立大根堆还是小根堆。
调整建立大根堆还是小根堆,只需要改变调整函数。父亲结点与孩子结点比较时的大于小于号。怎么通过仿函数来实现呢?
调整函数怎么修改:
- #pragma once
- #include<iostream>
- #include<deque>
- #include<vector>
- #include<list>
- using namespace std;
-
- namespace my{
- 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;
- }
- };
-
-
- template<class T,class Container = vector<T>,class Compare=less<T>>
- class priority_queue{
- public:
- priority_queue(){};
- template<class inputiterator>
- priority_queue(inputiterator first, inputiterator last){
- while (first != last){
- push(*first);
- first++;
- }
- }
- bool empty(){
- return _con.empty();
- }
- size_t size(){
- return _con.size();
- }
- T& top(){
- return _con.front();
- }
- const T& top()const{
- return _con.front();
- }
- void push(const T& val){
- _con.push_back(val);
- Adjustup(_con.size() - 1);
- }
- void pop(){
- swap(_con[0], _con[_con.size() - 1]);
- //少一个元素是size减减,交换后,直接删除最后一个元素
- _con.pop_back();
- Adjustdown(0);
- }
- private:
- void Adjustup(int child){
- int parent = (child - 1) / 2;
- Compare com;
- while (child){
- if (com(_con[parent],_con[child])){
- swap(_con[child], _con[parent]);
- child = parent;
- parent = (child - 1) / 2;
- }
- else{
- break;
- }
- }
- }
-
- void Adjustdown(int parent){
- int child = parent * 2 + 1;
- //定义一个对象
- Compare com;
- //不能减1,如果没有元素size()为0,类型size_t,减1就是最大的数(正数),会进入循环
- while ((size_t)child < _con. size() ){
-
- if (child + 1 < _con.size() && com(_con[child], _con[child + 1])){
- child++;
- }
- if (com(_con[parent], _con[child])){
- swap(_con[child], _con[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else{
- break;
- }
- }
- }
-
- Container _con;
- };
-
- void test_priority_queue(){
- int array[] = { 8, 4, 6, 2, 10 };
- priority_queue<int,vector<int>,greater<int>> pq(array, array + sizeof(array) / sizeof(int));
- cout << pq.size() << endl;
-
- while (!pq.empty()){
- cout << pq.top() << " ";
- pq.pop();
- }
- cout << endl;
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。