数据结构篇deque

这篇代码是写给自己看的,所以没什么注释,大家可以去看侯捷先生的《STL 源码剖析》

//mydeque.h
#include"myconstruct.h"
#include"mymemory.h"
using std::max;
using std::copy_backward;
/*deque是双向开头的连续线性空间,它动态地以分段连续空间组合而成,这个表面上deque的迭代器
 *支持随机访问,实则是假象,这里是以复杂的迭代器构架来维持此假象,我学习stl deque的目的是
 *研究它迭代器的构造,而非实用性;
 */
/*deque采用一块map作为主控,这里的map是一小块连续空间,其中的每个元素都是指针,指向另一块
 *连续的线性空间,称为缓冲区,缓冲区是存储主体,允许指定缓冲区的大小,默认情况下为512byte
 */
/*结构                   ——————————————————————————
 *map 指向一段区域|               |node|                                                 |
 *                         ——————————————————————————
 *每个node指向一片连续空间
 */
//BufSiz为缓冲区的大小,意为BufSiz个元素大小
template<typename T,typename Ref,typename Ptr,size_t BufSiz>
struct __deque_iterator
{
	typedef __deque_iterator<T,T&,T*,BufSiz>  iterator;
	typedef __deque_iterator<T,const T&,const T*> const_iterator;
	static size_t buffer_size(){return __deque_buf_size(BufSize,sizeof(T))};

	typedef random_iterator_tag iterator_category;
	typedef T                             value_type;
	typedef Ptr                           pointer;
	typedef Ref                           reference;
	typedef size_t                       size_type;
	typedef ptrdiff_t                    difference_type;
	typedef T**                          map_pointer;

	typedef __deque_iterator   self;
	//保持与容器的联结
	T* cur;//所指元素;这里的cur依然保持迭代器特征,如果在最前端,则指向最前端元素,
	//如果在最后端指向最后端的下一个元素
	T* first;//所指元素所在的缓冲区的头
	T* last;//所指元素所在的缓冲区的尾
	map_pointer node;//指向这一缓冲区的在map中的节点位置

private:
	//辅助函数
	void set_node(map_pointer new_node)//切换node
	{
		node=new_node;
		first=*new_node;
		last=first+difference_type(buffer_size());
	}
public:
/*---------------------重载的操作符-------------------------------------------*/
	//必要的操作符
	reference operator*() const {return *cur;}
	pointer    operator->() const {return &(operator*());}

	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;}
	
	//支持随机存取的实现
	difference_type operator-(const self& x) const
	{return difference_type(buffer_size())*(node-x.node-1) + (cur-first)+(x.last-x.cur);}

	self& operator+=(difference_type n);
	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);}

	//判断操作符
	bool operator==(const self& x) const{return cur==x.cur;}
	bool operator!=(const self& x) const {return !(*this==x);}
	bool operator<(const self& x)const
	{return (node==x.node)?(cur<x.cur):(node<x.node);}




};
//全局函数,如果n不为0,那么返回n;如果n为0,那么使用默认值512byte,返回值为512/sz
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));
}
//---------------------------------------------------------------------------
template<typename T,typename Ref,typename Ptr,size_t BufSiz>
typename __deque_iterator<T,Ref,Ptr,BufSiz>::self& 
	__deque_iterator<T,Ref,Ptr,BufSiz>::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;
}
//-------------------------------------------------------------------------------------------

template<typename T,typename Alloc=alloc,size_t BufSiz=0>
class deque
{
public:
	typedef T value_type;
	typedef value_type* pointer;
	typedef size_t     size_type;
	typedef const value_type* const_pointer;
	typedef value_type&  reference;
	typedef const value_type& const_reference;
	typedef ptrdiff_t  difference_type;
	
	typedef __deque_iterator<T,T&,T*,BufSiz>   iterator;
protected:
	//元素的指针的指针
	typedef pointer* map_pointer;
	//Data member
	size_type  map_size;//map所指区域的大小
	map_pointer map;
	iterator start;//第一个节点,用iterator包含缓冲区的信息
	iterator finish;//last迭代器
protected:
	//配置缓冲区中的元素
	typedef simple_alloc<value_type,Alloc>  data_allocator;
	//配置map中的元素,即node
	typedef simple_alloc<pointer,Alloc>   map_allocator;

public:
	deque(int n,const value_type& value)
		:map_size(0),start(),finish(),map(0){fill_initialize(n,value);}

	iterator begin(){return start;}
	iterator end(){return finish;}
	size_type buffer_size(){return iterator::buffer_size();}
	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;}
	size_type max_size() const {return size_type(-1);}//什么意思?
	bool empty() const {return finish==start;}
public:
	void push_back(const value_type& t);
	void push_front(const value_type& t);
	void pop_back();
	void pop_front();
	void clear();//清除元素,最后留一个缓冲区
	iterator erase(iterator pos);
	iterator insert(iterator position,const value_type& x);
private:
	//辅助函数
	void fill_initialize(size_type n,const value_type& value);
	void create_map_and_node(size_type num_elem);
	value_type* allocate_node();//分配一个缓冲区
	void deallocate_node(value_type* p);//释放一个缓冲区

	void push_back_aux(const value_type& t);
	void push_front_aux(const value_type& t);
	void pop_back_aux();
	void pop_front_aux();

	iterator insert_aux(iterator pos,const value_type& x);
	//以下三个函数解决:什么时候map需要重新整治?
	void reserve_map_at_back(size_type nodes_to_add=1);
	void reserve_map_at_front(size_type nodes_to_add=1);
	void reallocate_map(size_type nodes_to_add,bool add_at_front);

};
//----------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::fill_initialize(size_type n,const value_type& value)
{
	create_map_and_nodes(n);
	map_pointer cur;
	for(cur=start.node;cur<finish.node;++cur)
		uninitialized_fill(*cur,*cur+buffer_size(),value);
	//最后一个节点的值设定:
	uninitialized_fill(finish.first,finish.cur,value);
}
//------------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
deque<T,Alloc,BufSiz>::value_type*  deque<T,Alloc,BufSiz>::allocate_node()
{
	return data_allocator::allocate(buffer_size());
 }
//--------------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::deallocate_node(value_type* p)
{
	data_allocator::deallocate(buffer_size());
}
//------------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::create_map_and_node(size_type num_elem)
{
	//需要的map节点数:元素个数/每个缓冲区可容纳的元素数  +1
	size_type num_node=num_elem/buffer_size()+1;
	//一个map要管理的结点数最少是8个,最多是所需结点数加2,(前后各预留一个)
	map_size=max(8,num_node+2);
	map=map_allocator::allocate(map_size);
	//map配置完毕

	//令map从中央开始扩增
	map_pointer nstart=map+(map_size-num_node)/2;
	map_pointer nfinish=nstart+num_node-1;
	map_pointer cur;
	try{
		//为每个节点配置缓冲区
		for(cur=nstart;cur<=nfinish;++cur)
			*cur=allocate_node();
	}catch(...){
		//commit or rollback
		for(cur=nstart;cur!=NULL;++cur)
			deallocate_node(*cur);
	}
	start.set_node(nstart);
	finish.set_node(nfinish);
	start.cur=start.first;
	finish.cur=finish.first+num_elem%buffer_size();
}
//-----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_back(const value_type& t)
{
	if(finish.cur!=finish.last-1){
		//最后缓冲区还有两个以上的备用空间
		construct(finish.cur,t);
		++finish.cur;
	}else{
		//只剩一个元素的备用空间
		push_back_aux(t);
	}
}
//----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_back_aux(const value_type& t)
{
	value_type t_copy=t;
	reserve_map_at_back();//若符合某种条件则必须重换一个map
	*(finish.node+1)=allocate_node();
	try{
	construct(finish.cur,t_copy);
	finish.set_node(finish.node+1);
	finish.cur=finish.first;
	}catch(...){
		finish.set_node(finish.node-1);
		finish.cur=finish.last-1;
		deallocate_node(*(finish.node+1));
		throw;
	}
}
//------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_front(const value_type& t)
{
	if(start.cur!=start.first){
		construct(start.cur-1,t);
		--finish.cur;
	}else{
		push_front_aux(t);
	}
}
//---------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_front_aux(const value_type& t)
{
	value_type t_copy=t;
	reserve_map_at_front();
	*(start.node-1)=allocate_node();
	try{
		start.set_node(start.node-1);
		start.cur=start.last-1;
		construct(start.cur,t_copy);
	}catch(...){
		//commit or rollback
		start.set_node(start.node+1);
		start.cur=start.first;
		deallocate_node(*(start.node-1));
		throw;
	}
}
//-------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::reserve_map_at_back(size_type nodes_to_add=1)
{
	if(nodes_to_add+1>map_size-(finish.node-map)){
		//尾部空间不足,需要换一个map
		reallocate_map(nodes_to_add,false);
	}
}
//----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::reserve_map_at_front(size_type nodes_to_add=1)
{
	if(nodes_to_add>start.node-map){
		reallocate_map(nodes_to_add,true);
	}
}
//------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::reallocate_map(size_type nodes_to_add,bool add_at_front)
{
	size_type old_num_nodes=finish.node-start.node+1;
	size_type new_num_nodes=old_num_nodes+nodes_to_add;

	map_pointer new_nstart;
	if(map_size>2*new_num_nodes){
		new_nstart=map+(map_size-new_num_nodes)/2+(add_at_front?nodes_to_add:0);
		if(new_nstart<start.node)
			copy(start.node,finish.node+1,new_nstart);
		else
			copy_backward(start.node,finish.node+1,new_nstart+old_num_nodes);
	}else{
		size_type new_map_size=map_size+max(map_size,nodes_to_add)+2;
		//配置新空间
		map_pointer new_map=map_allocator::allocate(new_map_size);
		new_nstart=new_map+(new_map_size-new_num_nodes)/2+(add_at_front?nodes_to_add:0);
		copy(start.node,finish.node+1,new_nstart);
		map_allocator::deallocate(map,map_size);
		map=new_map;
		map_size=new_map_size;
	}
	start.set_node(new_nstart);
	finish.set_node(new_nstart+old_num_nodes-1);
}
//-----------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_back()
{
	if(finish.cur!=finish.first){
		--finish.cur;
		destroy(finish.cur);
	}else{
		pop_back_aux();
	}
}
//---------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_back_aux()
{
	deallocate_node(*(finish.node));
	finish.set_node(finish.node-1);
	finish.cur=finish.last-1;
	destroy(finish.cur);
}
//-----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_front()
{
	if(start.cur!=start.last-1){
		destroy(start.cur);
		++start.cur;
	}else{
		pop_front_aux();
	}
}
//---------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_front_aux()
{
	destroy(start.cur);
	deallocate_node(*(start.node));
	start.set_node(start.node+1);
	start.cur=start.first;
}
//-----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::clear()
{
	for(map_pointer node=start.node+1;node<finish.node;++node){
		destroy(*node,*node+buffer_size());
		deallocate_node(*(node));
	}
	if(start.node!=finish.node){
		destroy(start.cur,start.last);
		destroy(finish.first,finish.cur);
		deallocate_node(*(finish.node));
	}else{//只有一个缓冲区
		destroy(start.cur,finish.cur);//析构所有元素
		finish=start;
	}
}
//-------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
typename deque<T,Alloc,BufSiz>::iterator deque<T,Alloc,BufSiz>::erase(iterator pos)
{
	iterator next=pos;
	++next;
	difference_type  index=pos-start;
	if(index<(size()>>1)){//清除元素之前的元素比较少
		copy_backward(start,pos,next);
		pop_front();
	}else{
		copy(next,finish,pos);
		pop_back();
	}
	return start+index;
}
//---------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
typename deque<T,Alloc,BufSiz>::iterator 
	deque<T,Alloc,BufSiz>::insert(iterator position,const value_type& x)
{
	if(position.cur==start.cur){
		push_front(x);
		return start;
	}else if(position.cur==finish.cur){
		push_back(x);
		iterator tmp=finish;
		--tmp;
		return tmp;
	}else{
		return insert_aux(position,x);
	}
}
//-----------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
typename deque<T,Alloc,BufSiz>::iterator 
	deque<T,Alloc,BufSiz>::insert_aux(iterator pos,const value_type& x)
{
	difference_type index=pos-start;
	value_type x_copy=x;
	if(index<size()/2){
		push_front(front());
		iterator front1=start;
		++front1;
		iterator front2=front1;
		++front2;
		pos=start+index;
		iterator pos1=pos;
		++pos1;
		copy(front2,pos1,front1);
	}else{
		push_back(back());
		iterator back1=finish;
		--back1;
		iterator back2=back1;
		--back2;
		pos=start+index;
		copy_backward(pos,back2,back1);
	}
	*pos=x_copy;
	return pos;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值