deque C++实现

本文介绍了如何模仿C++标准库STL中的deque容器进行实现。deque作为一种介于vector和list之间的数据结构,其设计思想在代码中得到了体现。提供的代码简洁明了,便于理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模仿源码,对deque进行了实现。deque是vector和list的折中。与其说deque是stl中的一个组件不如说是一种设计思想。代码如下,虽注释较少但简单易懂。

/*copyright(c):2014-2020.written by zx 2014.5  
*/

#include<iostream>
#include<algorithm>
#include<type_traits>
using namespace std;

/*buffer size set*/
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));
}

/*一些空间配置器里面的函数*/
struct __false_type{};
struct __true_type{};  
struct input_iterator_tag {};

template<class T,class Ref,class Ptr,size_t BufSiz>

class Deque_iterator{
public:
	typedef Deque_iterator<T,T&,T*,BufSiz> iterator;
	typedef Deque_iterator<T,const T&,const T*,BufSiz> const_iterator;
	static size_t buffer_size(){return _deque_buf_size(BufSiz,sizeof(T));}
	//5个基本的迭代器型别
	typedef random_access_iterator_tag iterator_category; 
    typedef T value_type;  
    typedef T* pointer;  
    typedef T& reference;  
    typedef size_t size_type;  
    typedef ptrdiff_t difference_type; 
	typedef T** map_pointer;

	typedef Deque_iterator self;
	T* cur; //访问缓冲区
	T* first ; //指向缓冲区头
	T* last; // 指向缓冲区尾
	map_pointer node; //map中控器
	Deque_iterator():first(0),cur(0),last(0),node(0){}
	Deque_iterator(T* x,map_pointer y):cur(x),first(*y),last(*y+buff_size()),node(y){}
	Deque_iterator(const Deque_iterator& x ):
	cur(x.cur),first(x.first),last(x.last),node(x.node){}	
	void set_node(map_pointer new_node){
		node = new_node;
		first = *new_node;
		last = first + difference_type(buffer_size());
	}
	reference operator*()const{return *cur;}
	pointer operator->()const{return &(operator*());}
	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){
		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;
	}
	bool operator==(const self& x)const{return (cur == x.cur);}
	bool operator!=(const self& x)const{return (cur != x.cur);}
	bool operator<(const self& x)const{//同一个节点或者不同节点
		return node == x.node?(cur<x.cur):(node<x.node);
	}
	reference operator[](difference_type n) const { return *(*this + n); }
};

template<class T,size_t BufSize = 0>
class Deque{
public:
	typedef T value_type;
	typedef value_type* pointer;
	typedef value_type& reference;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
public:
	typedef Deque_iterator<T,T&,T*,BufSize> iterator;
protected:
	typedef pointer* map_pointer; // 中控器
	static size_type buffer_size(){
		return _deque_buf_size(BufSize,sizeof(value_type));
	}
	static size_type initial_map_size() { return 8; }  
protected:
	iterator start;
	iterator finish;
	map_pointer map;
	size_type map_size; // map容量
private:
	inline void destroy(iterator first1, iterator last1)  
	{  
		__destroy(first1, last1, pointer(0));  
	}
	inline void __destroy(iterator first, iterator last, T*)  
	{  
		//typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;  
		//__destroy_aux(first, last, __false_type);  
		__destroy_aux(first, last); 
	}  
	inline void  __destroy_aux(iterator first, iterator last)  
	{  
		for ( ; first < last; ++first)  
			destroy(&*first);  
	}  
	inline void destroy(pointer first,pointer last){
		for(;first<last;++first)
			destroy(first);
	}
	inline void destroy(T* pointer)  
	{  
		pointer->~T(
### C++ 实现 `deque` 数据结构 在 C++ 中,标准模板库(STL)已经提供了高效的双端队列实现——`std::deque`。此容器支持快速的随机访问迭代、常数时间内的前端和后端插入/删除操作。 #### 创建并初始化 `deque` 可以使用多种方法来创建和初始化一个 `deque` 对象: ```cpp #include <iostream> #include <deque> using namespace std; int main() { // 初始化 deque 并赋初值 deque<int> d = {1, 2, 3}; // 输出初始状态下的 deque 元素 cout << "Initial elements are: "; for (auto& elem : d) { cout << elem << ' '; } cout << endl; } ``` 上述代码展示了如何通过列表初始化语法定义一个新的整型 `deque`[^1]。 #### 插入元素到 `deque` 为了向 `deque` 添加新项,可利用成员函数如 `push_back()` 或者更高效的方式是采用 `emplace_*` 方法直接构建对象而无需先创建临时变量再复制或移动它们: ```cpp void addElements(deque<int>& dq) { // 使用 push_back/push_front 来添加单个元素 dq.push_back(4); dq.push_front(-1); // 利用 emplace 在指定位置构造新元素而非拷贝已有实例 dq.emplace(dq.end(), 5); // 等价于 push_back(5),但在内部调用了构造函数 dq.emplace(dq.begin(), -2); // 类似地,在最前面增加一项 } // 打印当前 deque 的全部内容 template<typename T> void printDeque(const deque<T>& deq) { for (const auto& item : deq){ cout << item << " "; } cout << "\n"; } ``` 这段程序片段说明了怎样运用不同的插入技术扩展现有的 `deque` 结构体[^3]。 #### 遍历 `deque` 由于 `deque` 支持基于索引的操作,因此可以直接像处理数组那样对其进行遍历;另外也能够借助迭代器完成同样的工作: ```cpp void traverseByIndex(const deque<int>& dataQueue) { size_t sz = dataQueue.size(); for(size_t idx = 0 ;idx != sz;++idx){ cout<<dataQueue[idx]<<" "; } cout<<"\n"; } void iterateWithIterator(const deque<int>& iteratedDQ) { for(auto itr = iteratedDQ.cbegin();itr!=iteratedDQ.cend();++itr){ cout<<*itr<<" "; } cout<<"\n"; } ``` 这里给出了两种不同风格的遍历模式:一种是指针式的下标访问形式,另一种则是更加泛化的迭代器机制[^2]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值