std::deque
std::deque是区别于vector和list的一种有序容器,可以像vector一样高效的取下标,却别于vector, deque可以高效的前插入,自我成长也比vector要高效些。但deque的迭代器操作是没有vector高效的,对deque排序也是异常复杂的,deque的数据结构如下图所示。
简单的代码实现:
#include <algorithm> // deque是一个中控器(map)管理多个节点,该函数返回一个节点node存放元素的个数 inline size_t deque_buf_size(size_t __size) { return __size < 512 ? size_t(512 / __size) : size_t(1); } template <typename Tp, typename Ref, typename Ptr> struct Deque_iterator { typedef Deque_iterator<Tp, Tp&, Tp*> iterator; static size_t s_buffer_size() { return deque_buf_size(sizeof(Tp)); } typedef Tp value_type; typedef Ptr pointer; typedef Ref reference; typedef size_t size_type; typedef Tp** Map_pointer; // map是一个二维指针,指针数组里存放每一个buf的首地址 typedef Deque_iterator Self; Tp* m_cur; // 指向当前元素的指针 Tp* m_first; // 指向所在buf的首地址 Tp* m_last; // 指向所在buf的结尾,所以不指向实际元素 Tp** m_node; // map里的节点,指向所在buf首地址 Deque_iterator(Tp* x, Map_pointer y) : m_cur(x), m_first(*y), m_last(*y + s_buffer_size()), m_node(y) {} Deque_iterator() : m_cur(0), m_first(0), m_last(0), m_node(0) {} Deque_iterator(const iterator& x) : m_cur(x.m_cur), m_first(x.m_first), m_last(x.m_last), m_node(x.m_node) {} reference operator*() const { return *m_cur; } pointer operator->() const { return m_cur; } size_t operator-(const Self& x) const { return s_buffer_size() * (m_node - x.m_node - 1) + (m_cur - m_first) + (x.m_last - x.m_cur); } Self& operator++() { ++m_cur; if (m_cur == m_last) { m_set_node(m_node + 1); m_cur = m_first; } return *this; } Self operator++(int) { Self tmp = *this; ++*this; return tmp; } Self& operator--() { if (m_cur == m_first) { m_set_node(m_node - 1); m_cur = m_last; } --m_cur; return *this; } Self operator--(int) { Self tmp = *this; --*this; return tmp; } Self& operator+=(int n) { int offset = n + (m_cur - m_first); if (offset >= 0 && offset < (s_buffer_size())) { // 如果在单个buf里,直接偏移就可 m_cur += n; } else { int node_offset = offset > 0 ? offset / s_buffer_size() : -(-offset - 1) / s_buffer_size() - 1; m_set_node(m_node + node_offset); // 切换节点,m_first也变掉了 m_cur = m_first + (offset - node_offset * s_buffer_size()); } return *this; } Self operator+(int n) const { Self tmp = *this; return tmp += n; } Self& operator-=(int __n) { return *this += -__n; } Self operator-(int __n) const { Self tmp = *this; return tmp -= __n; } reference operator[](size_t n) const { return *(*this + n); } bool operator==(const Self& x) const { return m_cur == x.m_cur; } bool operator!=(const Self& x) const { return !(*this == x); } bool operator<(const Self& x) const { return (m_node == x.m_node) ? (m_cur < x.m_cur) : (m_node < x.m_node); } bool operator>(const Self& x) const { return x < *this; } bool operator<=(const Self& x) const { return !(x < *this); } bool operator>=(const Self& x) const { return !(*this < x); } // 设置节点 void m_set_node(Tp** new_node) { m_node = new_node; m_first = *new_node; m_last = m_first + s_buffer_size(); } }; template <typename Tp> class Deque_base { public: typedef Deque_iterator<Tp, Tp&, Tp*> iterator; Deque_base(size_t num_elements) : m_map(0), m_map_size(0), m_start(), m_finish() { m_initialize_map(num_elements); } ~Deque_base() { if (m_map) { for (Tp** node = m_start.m_node; node <= m_finish.m_node; ++node) { printf("%p\n",*node); // 释放每一个buf free(*node); *node = 0; } printf("\n"); free(m_map); // 释放map m_map = 0; } } protected: void m_initialize_map(size_t num_elements) { size_t num_nodes = num_elements / deque_buf_size(sizeof(Tp)) + 1; m_map_size = std::max((size_t)s_initial_map_size, num_nodes + 2); // +2是map前后都会预留空间 m_map = (Tp**)malloc(m_map_size * sizeof(Tp*)); Tp** nstart = m_map + (m_map_size - num_nodes) / 2; Tp** nfinish = nstart + num_nodes; for (Tp** cur = nstart; cur < nfinish; ++cur) { // map的每一个node指向一个buf缓存 *cur = (Tp*)malloc(deque_buf_size(sizeof(Tp)) * sizeof(Tp)); printf("%p\n", *cur); } printf("\n"); m_start.m_set_node(nstart); m_finish.m_set_node(nfinish - 1); m_start.m_cur = m_start.m_first; // 首个迭代器的当前元素就是第一个元素 // 最后一个元素后面跟着的空元素 m_finish.m_cur = m_finish.m_first + num_elements % deque_buf_size(sizeof(Tp)); } enum { s_initial_map_size = 8 }; Tp** m_map; //中控器,存放每个buf的首地址,用于管理buf size_t m_map_size; //指针数组的长度 iterator m_start; //指向第一个迭代器 iterator m_finish; //指向最后一个迭代器 }; template <class Tp> class Mydeque : public Deque_base<Tp> { typedef Deque_base<Tp> Base; public: typedef Tp value_type; typedef value_type* pointer; typedef value_type& reference; typedef size_t size_type; typedef typename Base::iterator iterator; protected: typedef pointer* Map_pointer; static size_t s_buffer_size() { return deque_buf_size(sizeof(Tp)); } using Base::m_map; using Base::m_map_size; using Base::m_start; using Base::m_finish; public: iterator begin() { return Base::m_start; } iterator end() { return m_finish; } reference operator[](size_type n) { return m_start[n]; } reference front() { return *m_start; } reference back() { iterator tmp = m_finish; --tmp; return *tmp; } size_type size() const { return m_finish - m_start; } bool empty() const { return m_finish == m_start; } public: Mydeque() : Base(0) {} Mydeque(size_type n) : Base(n) { for (iterator it = m_start; it != m_finish; ++it) { new (it.m_cur) Tp(); } } Mydeque(const Mydeque& x) : Base(x.size()) { iterator tmp = m_start; for (iterator it = x.begin; it != x.end(); ++it, ++tmp) { new (tmp.m_cur) Tp(*it); } } ~Mydeque() { for (iterator it = m_start; it != m_finish; ++it) { (it.m_cur)->~Tp(); } } void swap(Mydeque& x) { std::swap(m_start, x.m_start); std::swap(m_finish, x.m_finish); std::swap(m_map, x.m_map); std::swap(m_map_size, x.m_map_size); } public: void push_back(const value_type& t) { if (m_finish.m_cur != m_finish.m_last - 1) { // 如果buf还有空间 new (m_finish.m_cur) Tp(t); ++m_finish.m_cur; // 只需要改下m_cur } else { m_push_back_aux(t); } } void push_front(const value_type& t) { if (m_start.m_cur != m_start.m_first) { new (m_start.m_cur - 1) Tp(t); --m_start.m_cur; } else { m_push_front_aux(t); } } void pop_back() { if (m_finish.m_cur != m_finish.m_first) { --m_finish.m_cur; ((value_type*)m_finish.m_cur)->~value_type(); } else { m_pop_back_aux(); } } void pop_front() { if (m_start.m_cur != m_start.m_last - 1) { ((value_type*)m_start.m_cur)->~value_type(); ++m_start.m_cur; } else { m_pop_front_aux(); } } protected: // 只有在需要向后新增node时调用 void m_push_back_aux(const value_type& t) { m_reserve_map_at_back(); *(m_finish.m_node + 1) = (Tp*)malloc(deque_buf_size(sizeof(Tp)) * sizeof(Tp)); printf("m_push_back_aux, %p\n", *(m_finish.m_node + 1)); new (m_finish.m_cur) Tp(t); m_finish.m_set_node(m_finish.m_node + 1);// m_finish指向下一个地址的首地址 m_finish.m_cur = m_finish.m_first; } // 只有在需要向前新增node时调用 void m_push_front_aux(const value_type& t) { m_reserve_map_at_front(); *(m_start.m_node - 1) = (Tp*)malloc(deque_buf_size(sizeof(Tp)) * sizeof(Tp)); printf("m_push_front_aux, %p\n", *(m_start.m_node - 1)); m_start.m_set_node(m_start.m_node - 1); m_start.m_cur = m_start.m_last - 1; new (m_start.m_cur) Tp(t); } // m_finish要跳到上一个node的时候才使用 void m_pop_back_aux() { free(m_finish.m_first); m_finish.m_set_node(m_finish.m_node - 1); m_finish.m_cur = m_finish.m_last - 1; ((value_type*)m_finish.m_cur)->~value_type(); } // m_start要跳到下一个node的时候才使用 void m_pop_front_aux() { ((value_type*)m_start.m_cur)->~value_type(); free(m_start.m_first); m_start.m_set_node(m_start.m_node + 1); m_start.m_cur = m_start.m_first; } // 向后添加map空间 void m_reserve_map_at_back(size_type nodes_to_add = 1) { if (nodes_to_add + 1 > m_map_size - (m_finish.m_node - m_map)) { m_reallocate_map(nodes_to_add, false); } } // 向前添加map空间 void m_reserve_map_at_front(size_type nodes_to_add = 1) { if (nodes_to_add > size_type(m_start.m_node - m_map)) { m_reallocate_map(nodes_to_add, true); } } // 调整map空间大小 // nodes_to_add-- 新添加的节点数 // add_at_front true-向前添加 false-向后添加 void m_reallocate_map(size_type nodes_to_add, bool add_at_front) { { size_type old_num_nodes = m_finish.m_node - m_start.m_node + 1; size_type new_num_nodes = old_num_nodes + nodes_to_add; Tp** new_nstart; if (m_map_size > 2 * new_num_nodes) { new_nstart = m_map + (m_map_size - new_num_nodes) / 2 + (add_at_front ? nodes_to_add : 0); if (new_nstart < m_start.m_node) { // 从m_start.m_node拷贝到new_nstart开始递增拷贝 std::copy(m_start.m_node, m_finish.m_node + 1, new_nstart); } else { // 从m_finish.m_node + 1拷贝到new_nstart + old_num_nodes开始递减拷贝 std::copy_backward(m_start.m_node, m_finish.m_node + 1,new_nstart + old_num_nodes); } } else { size_type new_map_size = m_map_size + std::max(m_map_size, nodes_to_add) + 2; Tp** new_map = (Tp**)malloc(new_map_size * sizeof(Tp*)); new_nstart = new_map + (new_map_size - new_num_nodes) / 2 + (add_at_front ? nodes_to_add : 0); std::copy(m_start.m_node, m_finish.m_node + 1, new_nstart); free(m_map); m_map = new_map; m_map_size = new_map_size; } // 从新设置迭代器所在node m_start.m_set_node(new_nstart); m_finish.m_set_node(new_nstart + old_num_nodes - 1); } } };