C++提供了三种容器适配器(container adapter):stack,queue和priority_queue。stack和queue基于deque实现,priority_queue基于vector实现。
那么如何理解容器适配器?
本质上讲,它也是一种设计模式,我们可以把容器适配器想象成一个220v充电器,stack或者queue就是插座,我们可以根据不同的特性来转换(5v/10v)
1.模拟实现stack
#include<deque>
template<class T, class con = deque<T>>
class Stack {
public:
Stack(){}
void push(const T& val)
{
_c.push_back(val);
}
void pop()
{
_c.pop_back();
}
T& top()
{
return _c.back();
}
size_t size() const
{
return _c.size();
}
bool Empty() const
{
return _c.empty();
}
private:
con _c;
};
int main()
{
Stack<int>s;
s.push(1);
s.push(2);
s.push(3);
cout << s.top() << " ";
system("pause");
return 0;
}
这里我们使用的deque来实现stack,比如12345,尾插之后是12345,我们使用尾删,则pop顺序就是54321,这就维持里stack的LIFO特性
2.模拟实现queue
#include<deque>
template<class T, class con = deque<T>>
class Queue {
public:
Queue(){}
void push(const T& val)
{
_c.push_back(val);
}
void pop()
{
_c.pop_front();
}
T& back()
{
return _c.back();
}
T& front()
{
return _c.front();
}
size_t size()const
{
return _c.size();
}
bool empty()const
{
return _c.empty();
}
private:
con _c;
};
int main()
{
Queue<int>q;
q.push(1);
q.push(2);
q.push(3);
cout << q.front() << " ";
cout << q.size() << " ";
system("pause");
return 0;
}
同样,我们借助deque来实现queue,但我们pop时用的是头删,所以维护了queueFIFO的特性
注意:stack和queue同样可以用vector和list来实现
但是用vector实现,扩容代价太大,用list实现比deque更容易造成内存碎片
3.模拟实现priority_queue
priority_queue即优先队列,它的底层是一个堆,堆的调整需要支持随机访问,而vector比deque随机访问效率高,所以在这里我们借助vector来实现,需要指出的是,priority_queue需要给定比较规则即compare
#include<vector>
#include<algorithm>
template<class T,class con = vector<T>,class compare = std::greater<T>>
class priority_queue
{
public:
priority_queue()
{
std::make_heap(_c.begin(), _c.end(), _cmp);
}
void push(const T& val)
{
_c.push_back(val);
std::make_heap(_c.begin(), _c.end(), _cmp);
}
void pop()
{
std::pop_heap(_c.begin(), _c.end(), _cmp);
_c.pop_back();
}
bool empty()const
{
return _c.empty();
}
size_t size()
{
return _c.size();
}
T& top()
{
return _c.front();
}
private:
con _c;
compare _cmp;
};
int main()
{
priority_queue<int> q;
q.push(6);
q.push(1);
q.push(3);
cout << q.top() << " ";
system("pause");
return 0;
}