#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "public_func.h"
using namespace std;
namespace Namespace_deque
{
void test_deque()
{
cout << "test deque" << endl;
deque<string> deque;
char buf[10] = {0};
clock_t timestart = clock();
//测试生成数据时间
for (long i = 0; i < MAXSIZE; i++)
{
try
{
snprintf(buf, 10, "%d", rand());
deque.push_back(string(buf)); //支持push_back
//deque.push_front(string(buf)); //支持push_front
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
abort(); //程序常退出
}
}
cout << "time(ms) = " << (clock() - timestart) << endl;
cout << "deque.size() = " << deque.size() << endl;
cout << "deque.max_size() = " << deque.max_size() << endl;
cout << "deque.front() = " << deque.front() << endl;
cout << "deque.back() = " << deque.back() << endl;
//测试查找时间
string target = get_a_string_target();
timestart = clock();
//find查找
{
auto pItem = ::find(deque.begin(), deque.end(), target);
cout << "::find(), time = " << (clock()-timestart) << endl;
if (pItem != deque.end())
{
cout << "found, " << *pItem << endl;
}
else
{
cout << "not found!" << endl;
}
}
//sort + bsearch
{
timestart = clock();
::sort(deque.begin(), deque.end());
cout << "sort, time(ms) = " << (clock()-timestart) << endl;
}
}
}
int main(int argc, char *argv[])
{
cout << "----------STL DEQUE BEGIN------------\n" << endl;
Namespace_deque::test_deque();
cout << "\n-----------STL DEQUE END-----------" << endl;
system("pause");
return 0;
}
原理:分段连续空间:对外声称为连续空间,实际内部是以一个vector和若干数组组成,vector元素中存储每个连续空间地址
//deque源码
template <class T, class Alloc=alloc, size_t BufSize=0>
class deque{
public:
typedef T value_type;
typedef __deque_iterator<T,T&,T*,BufSize> iterator; //目前三个模板参数,新版本只有1个模板参数
protected:
typedef pointer* map_pointer; //T**
protected:
iterator start; //首元素迭代器
iterator finish;
map_pointer map
size_type map_size;
public:
iterator begin(){return start;};
iterator end() {return finish;}
size_type size() const {return finish - start;}
};
//计算buf_size大小
inline size_t __deque_buf_size(size_t n, size_t sz){
return n!=0 ? n : (sz<512 ? size_t(512/sz) : size_t(1));
}
//deque迭代器
template <class T, class Ref, class Ptr, size_t BufSize>
struct __deque_iterator{
typedef random_access_iterator_tag iterator_category; //随机访问迭代器
...
typedef T** map_pointer;
//成员
T* cur;
T* first;
T* last;
map_pointer node;
};
//deque::insert() 插入元素
iterator insert(iterator position, const value_type& x){
if (position.cur == start.cur){ //如果插入元素是deque最前端,则直接push_front()
push_front(x);
return start;
}
else if (position.cur == finish.cur){//如果插入元素是最尾端,则push_back()
push_back(x);
iterator tmp = finish;
--tmp;
return tmp;
}
else{
return insert_aux(position, x); //插入在中间
}
};
template<class T, class Alloc, size_t BufSize>
typename deque<T, Alloc, BufSize>::iterator
deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x){
difference_type index = pos-start; //插入位置之前元素个数
value_type x_copy = x;
if (index < size()/2){ //如果插入点之前元素个数比之后元素个数少,则在最前端加入第1个元素,然后搬移插入位置之前数据往前一格
push_front(front());
...
copy(front2, pos1, front1);
}
else{ //如果插入点之后元素个数比之前元素个数少,则在最尾端加入第1个元素,然后搬移插入位置之前数据往后一格
push_back(back());
...
copy_backward(pos, back2, back1);
}
*pos = x_copy; //插入新元素
return pos;
}
//deque模拟连续空间全是deque_iterator功劳
reference operator[size_type n](){
return start[difference_type[n];];
}
reference front(){ return *start;}
reference back() {
iterator tmp = finish;
--tmp;
return *tmp;
}
size_type size() const{return finish-start;}
bool empty const(){return finish == start;};
reference operator*() const{return *cur;}
pointer operator->() const{return &(operator*());}
//制造连续空间假象1
difference_type operator-(const self& x) const{
return difference_type(buffer_size()) * (node - x.node -1) + (cur-first) + (x.last - x.cur);
}
self& operator++(){
++cur; //移动元素
if (cur == last){
set_node(node+1):
cur = first;
}
return *this;
}
self operator++(int){
self tmp = *this;
++*this;
return tmp;
}
self& operator--(){
if (cur == first){
set_node(node-1):
cur = last;
}
--cur; //移动元素
return *this;
}
self operator--(int){
self tmp = *this;
--*this;
return tmp;
}
self& operator+=(difference_type n){
difference_type offset = n + (cur - first);
if (offset > 0 && offset < difference_type(buffer_size()))
cur += n; //在同一分段内
else{ //不在同一分段内
difference_type node_offset = offset > 0 ? offset / difference_type(buffer_size()) : -difference_type((-offset-1) / buffer_size()) -1;
set_node(node + node_offset);
cur = first + (offset - node_offset * difference_type(buffer_size()));
}
return *this;
}
self operator+(difference_type n) const {
self tmp = *this;
return tmp += n;
}
self& operator-=(difference_type n){
return (*this += -n);
}
self operator-(difference_type n) const{
self tmp = *this;
return tmp -= n;
}
reference operator[](difference_type n) const{
return *(*this+n);
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "public_func.h"
using namespace std;
namespace Namespace_stack
{
void test_stack()
{
cout << "test stack" << endl;
stack<string> stack;
char buf[10] = {0};
clock_t timestart = clock();
//测试生成数据时间
for (long i = 0; i < MAXSIZE; i++)
{
try
{
snprintf(buf, 10, "%d", rand());
stack.push(string(buf)); //入栈
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
abort(); //程序常退出
}
}
cout << "time(ms) = " << (clock() - timestart) << endl;
cout << "stack.size() = " << stack.size() << endl;
cout << "stack.top() = " << stack.top() << endl;
stack.pop(); //出栈
cout << "stack.size() = " << stack.size() << endl;
cout << "stack.top() = " << stack.top() << endl;
}
}
int main(int argc, char *argv[])
{
cout << "----------STL STACK BEGIN------------\n" << endl;
Namespace_stack::test_stack();
cout << "\n-----------STL STACK END-----------" << endl;
system("pause");
return 0;
}
template<class T, class Sequence = deque<T>> //默认使用deque,可使用list和deque, deque效率更高
class stack{
protected:
Sequence c; //底层容器
public:
bool empty() const{return c.empty();}
size_type size() const {return c.size();}
reference top(){return c.back();};
void push(const value_type& x) {c.push_back();}
void pop(){c.pop_back();}
};
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "public_func.h"
using namespace std;
namespace Namespace_queue
{
void test_queue()
{
cout << "test queue" << endl;
queue<string> queue;
char buf[10] = {0};
clock_t timestart = clock();
//测试生成数据时间
for (long i = 0; i < MAXSIZE; i++)
{
try
{
snprintf(buf, 10, "%d", rand());
queue.push(string(buf)); //入队
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
abort(); //程序常退出
}
}
cout << "time(ms) = " << (clock() - timestart) << endl;
cout << "queue.size() = " << queue.size() << endl;
cout << "queue.front() = " << queue.front() << endl;
cout << "queue.back() = " << queue.back() << endl;
queue.pop(); //出队
cout << "queue.size() = " << queue.size() << endl;
cout << "queue.front() = " << queue.front() << endl;
cout << "queue.back() = " << queue.back() << endl;
}
}
int main(int argc, char *argv[])
{
cout << "----------STL QUEUE BEGIN------------\n" << endl;
Namespace_queue::test_queue();
cout << "\n-----------STL QUEUE END-----------" << endl;
system("pause");
return 0;
}
```cpp
template<class T, class Sequence = deque<T>> //默认使用deque,可使用list和deque, deque效率更高
class queue{
protected:
Sequence c; //底层容器
public:
bool empty() const{return c.empty();}
size_type size() const {return c.size();}
reference front(){return c.front();}
reference back(){return c.back();}
void push(const value_type& x) {c.push_back();}
void pop(){c.pop_back();}
};
底层结构选择原则:stack和queue所有的接口转调用都能编译通过,都能适配,则可支持
1)stack和queue不允许遍历,则不提供iterator
2)stack和queue可以选择list或deque作底层结构
3)stack可以选择vector作底层结构,queue不能选择vector作底层结构
4)stack和queue都不可以选择set或map作底层结构