对于 deque 这个东西在初学 STL 的时候好像有看过,可能是因为其特性不足够吸引人吧,尽然被忽略了。前两天在看 Effective STL 的时候才发现这个东东还是蛮有用的,就此总结一下:
首先 deque 读作 deck ,中译双端队列。
即为双端,其内部必然有两个队列,如果将队列看作是 STL 中的 vector,则 deque 可以看成是如下结构:
注意,在 STL 的实现中 deque 必不是如上的 vector 的简单封装,这里为了说明 deque 的特性,特用此例。
而 deque 的插入和删除函数如下:
由上可看出对 deque 的两端进行插入删除操作,实际上是对内部存储的两个增长方向相反的 vector 的尾部进行操作,所以除了很少情况的内部调整(如:code-a,code-b 处)外,总是能达到 O(1) 的运算效率。
而 deque 的 size() 和 随机访问操作也可以看作是:
Deque 的 iterator 可以看作上面的 operator[] 的一个封装,这里就不列出了。
需要注意的是,根据 deque 的原理,如果在 deque 的中间插入或者删除了数据,则所有的 iterator,reference 都会失效。
首先 deque 读作 deck ,中译双端队列。
即为双端,其内部必然有两个队列,如果将队列看作是 STL 中的 vector,则 deque 可以看成是如下结构:
template<typename T>
class deque {
private:
vector<T> front_que_;
vector<T> back_que_;
};
class deque {
private:
vector<T> front_que_;
vector<T> back_que_;
};
注意,在 STL 的实现中 deque 必不是如上的 vector 的简单封装,这里为了说明 deque 的特性,特用此例。
而 deque 的插入和删除函数如下:
...
template<typename T> void deque<T>::push_back(const T &t) {
back_que_.push_back(t);
}
template<typename T> void deque<T>::pop_back() {
if (back_que_.empty())
front_que_.pop_front(); // code-a
else
back_que_.pop_back();
}
template<typename T> void deque<T>::push_front(const T &t) {
front_que_.push_back(t);
}
template<typename T> void deque<T>::pop_front(const T &t) {
if (front_que_.empty())
back_que_.pop_front(); // code-b
else
front_que_.pop_back();
}
...
template<typename T> void deque<T>::push_back(const T &t) {
back_que_.push_back(t);
}
template<typename T> void deque<T>::pop_back() {
if (back_que_.empty())
front_que_.pop_front(); // code-a
else
back_que_.pop_back();
}
template<typename T> void deque<T>::push_front(const T &t) {
front_que_.push_back(t);
}
template<typename T> void deque<T>::pop_front(const T &t) {
if (front_que_.empty())
back_que_.pop_front(); // code-b
else
front_que_.pop_back();
}
...
由上可看出对 deque 的两端进行插入删除操作,实际上是对内部存储的两个增长方向相反的 vector 的尾部进行操作,所以除了很少情况的内部调整(如:code-a,code-b 处)外,总是能达到 O(1) 的运算效率。
而 deque 的 size() 和 随机访问操作也可以看作是:
...
template<typename T> deque<T>::size_type
deque<T>::size() const {
return back_que_.size() + front_que_.size();
}
template<typename T> const T &
deque<T>::operator[] (deque<T>::size_type index) const {
if (index < front_que_.size())
return front_que_[front_que_.size() - index - 1];
else
return back_que_[index - front_que_.size()];
}
...
template<typename T> deque<T>::size_type
deque<T>::size() const {
return back_que_.size() + front_que_.size();
}
template<typename T> const T &
deque<T>::operator[] (deque<T>::size_type index) const {
if (index < front_que_.size())
return front_que_[front_que_.size() - index - 1];
else
return back_que_[index - front_que_.size()];
}
...
Deque 的 iterator 可以看作上面的 operator[] 的一个封装,这里就不列出了。
需要注意的是,根据 deque 的原理,如果在 deque 的中间插入或者删除了数据,则所有的 iterator,reference 都会失效。