使用迭代器实现双向队列deque----完整源代码

双向队列头文件Deq1.h

#include<iostream>
#include<stdlib.h>
#include<stddef.h>
#include<math.h>
#include<algorithm>
using namespace std;
#ifdef __STL_USE_EXCEPTIONS
#define __STL_TRY   try
#define __STL_UNWIND(action)   catch(...) { action; throw; }
#else
#define __STL_TRY
#define __STL_UNWIND(action)
#endif


inline size_t __deque_buf_size(size_t n, size_t sz)//n用户自定义元素个数
{
	return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));//512默认分配512字节
}


template<class T1, class T2>
inline void construct(T1* p, const T2& value)
{
	new (p)T1(value);
}

template<class T>
inline void destroy(T* ptr)
{
	ptr->~T();
}

template<class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last)
{
	for (; first != last; ++first)
		destroy(&*first);
}

//将内存接口包装,以满足STL标准接口
template<class T, class Alloc>
class simple_alloc {
public:
	static T* allocate(size_t n)
	{
		T* result = (T*)malloc(sizeof(T) * n);         
		if (0 == result) exit(0);
		return result;
	}
	static void deallocate(T* p)
	{
		free(p);
	}
};


//deque iterator
template <class T, class Ref, class Ptr>
struct __deque_iterator {
	typedef __deque_iterator<T, T&, T*>  iterator;
	typedef __deque_iterator<T, const T&, const T*> const_iterator;
	static size_t buffer_size() { return __deque_buf_size(0, sizeof(T)); }

	// 未继承 std::iterator,所以必须自行撰写五个必要的迭代器相应型别
	typedef random_access_iterator_tag iterator_category; // (1)
	typedef T value_type; 				// (2)
	typedef Ptr pointer; 				// (3)
	typedef Ref reference; 				// (4)
	typedef size_t size_type;
	typedef ptrdiff_t difference_type; 	// (5)ptrdiff_t long int
	typedef T** map_pointer;

	typedef __deque_iterator self;

	// 保持与容器的联结
	T* cur;	// 此迭代器所指之缓冲区中的现行
	T* first;	// 此迭代器所指之缓冲区的头
	T* last;	// 此迭代器所指之缓冲区的尾(含备用空间)
	map_pointer node; //  指向指针数组map

	__deque_iterator(T* x, map_pointer y)
		: cur(x), first(*y), last(*y + buffer_size()), node(y) {}
	__deque_iterator() : cur(0), first(0), last(0), node(0) {}//使用的是这个
	__deque_iterator(const iterator& x)
		: cur(x.cur), first(x.first), last(x.last), node(x.node) {}
	~__deque_iterator(){}

	//  __deque_iterator<> 重载运算符

	reference operator*() const { return *cur; }//*iterator
	pointer operator->() const { return &(operator*()); }//iterator->cur

	difference_type operator-(const self& x) const {//iter1-iter2
		return difference_type(buffer_size()) * (node - x.node - 1) +//块间
			(cur - first) + (x.last - x.cur);//块内
	}

	self& operator++() {//++iter
		++cur;	// 切换至下一个元素
		/*
		  如果已达所在缓冲区的尾端
		  就切换至下一个节点(亦即缓冲区)的第一个元素。
		*/
		if (cur == last) {
			set_node(node + 1);
			cur = first;
		}
		return *this;
	}

	self operator++(int) {//iter++
		self tmp = *this;
		++* this;
		return tmp;
	}
	
	self& operator--() {//--iter
		/*
		如果已达所在缓冲区的头端,就切换至前一个节点(亦即缓冲区)
		的最后一个元素。
		*/
		if (cur == first) {
			set_node(node - 1);
			cur = last;
		}

		--cur;  // 切换至前一个元素
		return *this;
	}
	self operator--(int) {//iter--
		self tmp = *this;
		--* this;
		return tmp;
	}
	//实现随机存储。迭代器可以直接跳跃n个距离
	//要么直接在cur上面加,当碰到当前片段last,则重新换内存片段,再在cur上面加
	self& operator+=(difference_type n) {//iter+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 {//const+
		self tmp = *this;
		return tmp += n; // 调用operator+=
	}

	self& operator-=(difference_type n) { return *this += -n; }//iter-=n
	// 以上利用operator+= 来完成 operator-=

	self operator-(difference_type n) const {
		self tmp = *this;
		return tmp -= n; // 调用operator-=
	}
	//随机存取iter[]
	reference operator[](difference_type n) const { return *(*this + n); }
	// 以上调用operator*, operator+
	
	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);
	}
	//设置节点信息,在已经分配的连续内存片段上面取值或者存数值
	void set_node(map_pointer new_node) {
		node = new_node;
		first = *new_node;
		last = first + difference_type(buffer_size());
	}
};






template <class T, class Alloc = allocator<T>>
class deque {
public:
	typedef T value_type;
	typedef value_type* pointer;
	typedef const value_type* const_pointer;
	typedef size_t size_type;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef ptrdiff_t difference_type;

public:
	typedef __deque_iterator<T, T&, T*>iterator;//迭代器类

protected:
	typedef pointer* map_pointer;
	iterator start;//开始迭代器
	iterator finish;//结束迭代器
	iterator cur;
	map_pointer map;//指针数组map
	size_type map_size;//指针数组元素个数
	typedef simple_alloc<value_type, Alloc> data_allocator;//连续内存块 内存器
	typedef simple_alloc<pointer, Alloc>map_allocator;//指针数组 内存分配器
public:
	iterator begin() { return start; }
	iterator end() { return finish; }
	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); }
	T* allocate_node() { return data_allocator::allocate(buffer_size()); }
	static size_t buffer_size() { return __deque_buf_size(0, sizeof(T)); }
	static size_t initial_map_size() { return 8; }
	bool empty()const { return finish == start; }
	void creat_map_and_nodes(size_type num_elements);

	void fill_initialize(size_type n, const value_type& value);
	void push_back(const value_type& t);
	void push_back_aux(const value_type& t);
	void push_front(const value_type& t);
	void push_front_aux(const value_type& t);
	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);
	void pop_back();
	void pop_back_aux();
	void pop_front();
	void pop_front_aux();
	void clear();
	iterator erase(iterator first, iterator last);
	iterator insert(iterator position, const value_type& x);
	iterator insert_aux(iterator pos, const value_type& x);

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

};




template <class T, class Alloc>
void deque<T, Alloc>::fill_initialize(size_type n, const value_type& value) {
	creat_map_and_nodes(n);
	map_pointer cur;
	__STL_TRY
	{
		for (cur = start.node; cur < finish.node; ++cur)
			uninitialized_fill(*cur,*cur + buffer_size(),value);//初始化节点内存块buffer
		uninitialized_fill(finish.first, finish.cur, value);//尾部可能有多余空间
	}
}

template <class T, class Alloc>
void deque<T, Alloc>::creat_map_and_nodes(size_type num_elements)
{
	size_type num_nodes = num_elements / buffer_size() + 1;//计算nodes个数,用需要的元素总数除以每个buffer的大小,得到map中节点个数
	map_size = max(initial_map_size(), num_nodes + 2);//map的大小最小设置成8,要么设置成num_nodes+2的大小,可左右各增长一个
	map = map_allocator::allocate(map_size);//map内存分配
	map_pointer nstart = map + (map_size - num_nodes) / 2;//先使用map指针数组中间的位置,方便前后扩充
	map_pointer nfinish = nstart + num_nodes - 1;
	map_pointer cur;
	__STL_TRY{
		for (cur = nstart; cur <= nfinish; ++cur)
			*cur = allocate_node();//始化指针数组成员
	}
	start.set_node(nstart);
	finish.set_node(nfinish);
	start.cur = start.first;
	finish.cur = finish.first + num_elements % buffer_size();//向最后元素的后面一个元素形成[start , finish)左闭右开空间
}

template <class T, class Alloc>
void deque<T, Alloc>::push_back(const value_type& t)
{
	if (finish.cur != finish.last - 1) {//尾部还有一个以上的空间
		construct(finish.cur, t);//直接构造
		++finish.cur;//调整finish的cur+1
	}
	else {
		push_back_aux(t);//没有或者只剩下一个,添加node,然后构造
	}
}

template <class T, class Alloc>
void deque<T, Alloc>::push_back_aux(const value_type& t) {
	value_type t_copy = t;
	reserve_map_at_back();//加入后是否大于map内存空间
	*(finish.node + 1) = allocate_node();//分配节点,node
	__STL_TRY{
	  construct(finish.cur, t_copy);//构造元素
	  finish.set_node(finish.node + 1);
	  finish.cur = finish.first;//设定finish
	}
	__STL_UNWIND(deallocate_node(*(finish.node + 1)));//释放返回
}

template <class T, class Alloc>
void deque<T, Alloc>::push_front(const value_type& t)
{
	if (start.cur != start.first) {

		construct(start.cur - 1, t);
		--start.cur;
	}
	else
		push_front_aux(t);
}
template <class T, class Alloc>
void deque<T, Alloc>::push_front_aux(const value_type& t) {
	value_type t_copy = t;
	reserve_map_at_front();//是否需要重新分配map
	*(start.node - 1) = allocate_node();//分配node
	__STL_TRY{
	  start.set_node(start.node - 1);
	  start.cur = start.last - 1;
	  construct(start.cur, t_copy);
	}
}

template <class T, class Alloc>
void deque<T, Alloc>::reserve_map_at_back(size_type nodes_to_add)
{
	if (nodes_to_add + 1 > map_size - (finish.node - map))
		// 如果 map 尾端的节点备用空间不足
		// 符合以上条件则必须重换一个map(配置更大的,拷贝原来的,释放原来的)
		reallocate_map(nodes_to_add, false);
}

template <class T, class Alloc>
void deque<T, Alloc>::reserve_map_at_front(size_type nodes_to_add)
{
	if (nodes_to_add > start.node - map)
		// 如果 map 前端的节点备用空间不足
		// 符合以上条件则必须重换一个map(配置更大的,拷贝原来的,释放原来的)
		reallocate_map(nodes_to_add, true);
}

template <class T, class Alloc>
void deque<T, Alloc>
::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;
	/* 原map_size很充裕时只用调整下start和finish的位置就行了
   *此时并不用重新申请map,只需要调整一下位置
   *重新将已用的结点挪动到中间位置即可
   */
	if (map_size > 2 * new_num_nodes) {
		new_nstart = map + (map_size - new_num_nodes) / 2
			+ (add_at_front ? nodes_to_add : 0);//重新计算start和finish迭代器应处于的位置
		if (new_nstart < start.node)
			copy(start.node, finish.node + 1, new_nstart);//首部需要往后调整
		else//尾部需要往前调整
			copy_backward(start.node, finish.node + 1, new_nstart + new_num_nodes);
	}
	else {
		size_type new_map_size = map_size + max_size() + 2;//max(map_size, nodes_to_add) + 2;
		// 配置一块空间,准备给新map使用。
		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);
		// 把原map 内容拷贝过来。
		copy(start.node, finish.node + 1, new_nstart);
		// 释放原map
		map_allocator::deallocate(map);
		// 设定新map的起始位址与大小
		map = new_map;
		map_size = new_map_size;
	}
	// 重新设定迭代器 start 和 finish
	start.set_node(new_nstart);
	finish.set_node(new_nstart + new_num_nodes - 1);
}

template <class T, class Alloc>
void deque<T, Alloc>::pop_back() {
	if (finish.cur != finish.first) {
		// 最后缓冲区有一个(或更多)元素
		--finish.cur;		// 调整指针
		destroy(finish.cur);	// 将最后元素析构
	}
	else
		// 最后缓冲区没有任何元素
		pop_back_aux();		// 这里将进行缓冲区的释放工作
}
// 只有当finish.cur == finish.first时才会被调用。
template <class T, class Alloc>
void deque<T, Alloc>::pop_back_aux() {
	deallocate_node(finish.first);	// 释放最后一个缓冲区
	finish.set_node(finish.node - 1);	// 调整 finish 的状态,使指向
	finish.cur = finish.last - 1;		// 上一个缓冲区的最后一个元素
	destroy(finish.cur);				// 将该元素析构。
}

template <class T, class Alloc>
void deque<T, Alloc>::pop_front() {
	if (start.cur != start.last - 1) {
		// 第一缓冲区有一个(或更多)元素
		destroy(start.cur);	// 将第一元素析构
		++start.cur;			// 调整指针
	}
	else
		// 第一缓冲区仅有一个元素
		pop_front_aux();		// 这里将进行缓冲区的释放工作
}
// 只有当start.cur == start.last - 1时才会被调用。
template <class T, class Alloc>
void deque<T, Alloc>::pop_front_aux() {
	destroy(start.cur);				// 将第一缓冲区的第一个元素析构。
	data_allocator::deallocate(start.first);		// 释放第一缓冲区。
	start.set_node(start.node + 1);	// 调整 start 的状态,使指向
	start.cur = start.first;			//  下一个缓冲区的第一个元素。}

}

template <class T, class Alloc>
void deque<T, Alloc>::clear() {
	// 以下针对头尾以外的每一个缓冲区(它们一定都是饱满的)
	for (map_pointer node = start.node + 1; node < finish.node; ++node) {
		// 将缓冲区内的所有元素析构。
		destroy(*node, *node + buffer_size());
		// 释放缓冲区存储器
		data_allocator::deallocate(*node);
	}
	if (start.node != finish.node) {	// 至少有头尾两个缓冲区
		destroy(start.cur, start.last);	// 将头缓冲区的目前所有元素析构
		destroy(finish.first, finish.cur); // 将尾缓冲区的目前所有元素析构
		// 以下释放尾缓冲区。注意,头缓冲区保留。
		data_allocator::deallocate(finish.first);
	}
	else	// 只有一个缓冲区
		destroy(start.cur, finish.cur);	// 将此唯一缓冲区内的所有元素析构
		// 注意,并不释放缓冲区空间。这唯一的缓冲区将保留。
	finish = start;	// 调整状态
}

template <class T, class Alloc>
typename deque<T, Alloc>::iterator deque<T, Alloc>::erase(iterator first, iterator last) {
	if (first == start && last == finish) { // 如果清除区间就是整个 deque
		clear();							// 直接调用 clear() 即可
		return finish;
	}
	else {
		difference_type n = last - first;	// 清除区间的长度
		difference_type elems_before = first - start;// 清除区间前方的元素个数
		if (elems_before < (size() - n) / 2) {	// 如果前方的元素比较少,
			copy_backward(start, first, last); // 向后移动前方元素(覆盖清除区间)
			iterator new_start = start + n; // 标记 deque 的新起点
			destroy(start, new_start);	// 移动完毕,将冗余的元素析构
			// 以下将冗余的缓冲区释放
			for (map_pointer cur = start.node; cur < new_start.node; ++cur)
				data_allocator::deallocate(*cur);
			start = new_start;	// 设定 deque 的新起点
		}
		else {	// 如果清除区间后方的元素比较少
			copy(last, finish, first);	// 向前移动后方元素(覆盖清除区间)
			iterator new_finish = finish - n;	// 标记 deque 的新尾点
			destroy(new_finish, finish);		// 移动完毕,将冗余的元素析构
			// 以下将冗余的缓冲区释放
			for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
				data_allocator::deallocate(*cur);
			finish = new_finish;	// 设定 deque 的新尾点
		}
		return start + elems_before;
	}
}

// 在position 处插入一个元素,其值为 x
template <class T, class Alloc>
typename deque<T, Alloc>::iterator deque<T, Alloc>::insert(iterator position, const value_type& x) {
	if (position.cur == start.cur) {// 如果安插点是deque 最前端
		push_front(x);				// 交给push_front 去做
		return start;
	}
	else if (position.cur == finish.cur) { // 如果安插点是deque 最尾端
		push_back(x);					  // 交给push_back 去做
		iterator tmp = finish;
		--tmp;
		return tmp;
	}
	else {
		return insert_aux(position, x);	// 交给 insert_aux 去做
	}
}

template <class T, class Alloc>
typename deque<T, Alloc>::iterator deque<T, Alloc>::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;
}


测试代码

#include"Deq1.h"
#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	deque<int> ideq(135, 9);//一段连续缓冲区可以存放8个int=32字节初始化内存,并将135个元素初始化为9.
	cout << "size = " << ideq.size() << endl;//135 deque上面存储的元素个数
	
	for (int i = 0; i < ideq.size(); ++i)//随机读入
		ideq[i] = i;
	cout << endl << "读取" << endl;
	for (int i = 0; i < ideq.size(); ++i)//输出
	{
		cout << ideq[i];
		cout << ' ';
	}
	cout << endl;//0 1 2 3 ... 134
	ideq.push_back(135);//后端插入
	ideq.push_front(0); //前端插入
	cout << endl << "前后分别添加元素:" << endl;
	for (int i = 0; i < ideq.size(); ++i)//输出
	{
		cout << ideq[i];
		cout << ' ';
	}
	cout << endl;
	ideq.pop_front();
	cout << endl <<  "删除前端的元素:" << endl;
	for (int i = 0; i < ideq.size(); ++i)//输出
	{
		cout << ideq[i];
		cout << ' ';
	}
	cout << endl;
	deque<int>::iterator iter = ideq.begin();
	cout << "打印第一个元素的值:";
	cout << *iter << endl;
	iter++;
	cout << "右移一位元素:";
	cout << *iter << endl;
	iter--;
	ideq.insert(iter, 8);
	
	cout << endl <<  "开头插入8" << endl;
	for (int i = 0; i < ideq.size(); ++i)//输出
	{
		cout << ideq[i];
		cout << ' ';
	}
	cout << endl;
	ideq.erase(ideq.begin(), iter);
	cout << endl << "擦除8" << endl;
	for (int i = 0; i < ideq.size(); ++i)//输出
	{
		cout << ideq[i];
		cout << ' ';
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!感谢您的提问。要模拟银行单队列多窗口的情况,可以使用数据结构中的双向队列deque)来实现双向队列在这里可以用来存储客户的信息以及排队顺序。以下是一个简单的示例代码: ```python from collections import deque class BankQueue: def __init__(self, num_windows): self.num_windows = num_windows self.queue = deque() def enqueue(self, customer): self.queue.append(customer) def dequeue(self): if not self.is_empty(): return self.queue.popleft() else: return None def is_empty(self): return len(self.queue) == 0 def get_queue_size(self): return len(self.queue) def get_num_windows(self): return self.num_windows class Customer: def __init__(self, id): self.id = id def get_id(self): return self.id # 创建银行队列 bank_queue = BankQueue(3) # 模拟客户入队 for i in range(1, 11): customer = Customer(i) bank_queue.enqueue(customer) # 模拟客户办理业务 while not bank_queue.is_empty(): for window in range(bank_queue.get_num_windows()): customer = bank_queue.dequeue() if customer: print(f"窗口{window+1}正在为客户{customer.get_id()}办理业务") else: break ``` 上述代码中,BankQueue类代表银行的队列,通过双向队列实现了入队和出队操作。Customer类代表客户,每个客户有一个唯一的id。模拟时,先创建一个BankQueue对象,并指定窗口数量。然后依次将客户加入队列,最后通过循环模拟窗口依次为客户办理业务。 这只是一个简单的模拟示例,实际应用中可能需要更多的功能和细节处理。希望能对您有所帮助!如果您有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值