实现C++ Queue,双端队列与单端队列

手写C++ Queue,参考QQueue

分为双端队列和单端队列,单端队列继承自双端队列

类声明

双端
template<typename T>
	class Queue : public ContainerBase
	{
	public:
		explicit Queue() noexcept;
		Queue(const Queue&t)noexcept;
		Queue(Queue&&t)noexcept;

		Queue& operator= (const Queue& t)noexcept;
		Queue& operator= (Queue&& t)noexcept;

		~Queue();

		bool isEmpty()const noexcept { return m_size == 0; };
		uint size()const noexcept { return m_size; };
		Queue& pushBack(const T& t)noexcept;
		Queue& pushBack(T&& t)noexcept;
		Queue& pushFront(const T& t)noexcept;
		Queue& pushFront(T&& t)noexcept;

		T popBack();
		T popFront();

		T& head();
		T& tail();
		const T& at(int pos);
		void clear()noexcept;
	protected:

		template<typename T>
		struct Node
		{
			T data;
			Node* next = nullptr;
			Node * previous = nullptr;
		};
		using NodeT = Node<T>;

		NodeT * m_head;
		NodeT * m_tail;
		uint m_size;

		void _throw(bool v)const
		{
			if (v)
				throw std::out_of_range("Queue request out of range");
		}
	};
单端
template<typename T>
	class SQueue : public Queue<T>
	{
	public:
		SQueue() = default;
		~SQueue() = default;
		SQueue& enqueue(const T& t)noexcept;
		T dequeue();
		Queue& pushBack(const T& t) = delete;
		Queue& pushBack(T&& t) = delete;
		Queue& pushFront(const T& t) = delete;
		Queue& pushFront(T&& t) = delete;;

		T popBack() = delete;;
		T popFront() = delete;;
	};

类实现

双端链表
template<typename T>
	MContainer::Queue<T>::Queue() noexcept
	{
		m_head = new NodeT;
		m_tail = nullptr;
		m_size = 0;

	}

	template<typename T>
	MContainer::Queue<T>::Queue(const Queue&t) noexcept
	{
		m_size = t.m_size;
		NodeT* srcPtr = t.m_head->next;
		NodeT* desPtr = m_head;
		while (srcPtr != nullptr)
		{
			NodeT * node = new NodeT;
			node->data = srcPtr->data;
			desPtr->next = node;
			node->previous = desPtr;

			desPtr = node;
			srcPtr = srcPtr->next;
		}
		m_tail = desPtr;

	}

	template<typename T>
	MContainer::Queue<T>::Queue(Queue&&t) noexcept
	{
		if (this == &t)
			return;
		m_head->next = t.m_head->next;
		m_tail = t.m_tail;
		m_size = t.m_size;

		m_head->next = nullptr;
		t.m_size = 0;
	}

	template<typename T>
	Queue<T>& MContainer::Queue<T>::operator=(const Queue& t) noexcept
	{
		if (this == &t)
			return *this;
		m_size = t.m_size;
		NodeT* srcPtr = t.m_head->next;
		NodeT* desPtr = m_head;
		while (srcPtr != nullptr)
		{
			NodeT * node = new NodeT;
			node->data = srcPtr->data;
			desPtr->next = node;
			node->previous = desPtr;

			desPtr = node;
			srcPtr = srcPtr->next;
		}
		m_tail = desPtr;
	}

	template<typename T>
	Queue<T>& MContainer::Queue<T>::operator=(Queue&& t) noexcept
	{
		if (this == &t)
			return *this;
		m_head->next = t.m_head->next;
		m_tail = t.m_tail;
		m_size = t.m_size;

		m_head->next = nullptr;
		t.m_size = 0;
	}

	template<typename T>
	MContainer::Queue<T>::~Queue()
	{
		clear();
		delete m_head;
	}

	template<typename T>
	Queue<T>& MContainer::Queue<T>::pushBack(const T& t) noexcept
	{
		assert(m_size + 1 <= m_maxSize);
		NodeT * node = new NodeT;
		node->data = t;
		if (m_tail == nullptr)
		{
			node->previous = m_head;
			m_head->next = node;
		}
		else
		{
			node->previous = m_tail;
			m_tail->next = node;
		}

		m_tail = node;
		m_size++;
		return *this;
	}

	template<typename T>
	Queue<T>& MContainer::Queue<T>::pushBack(T&& t) noexcept
	{
		assert(m_size + 1 <= m_maxSize);
		NodeT * node = new NodeT;
		node->data = std::move(t);
		if (m_tail == nullptr)
		{
			node->previous = m_head;
			m_head->next = node;
		}
		else
		{
			node->previous = m_tail;
			m_tail->next = node;
		}

		m_tail = node;
		m_size++;
		return *this;
	}

	template<typename T>
	Queue<T>& MContainer::Queue<T>::pushFront(const T& t) noexcept
	{
		assert(m_size + 1 <= m_maxSize);
		NodeT * node = new NodeT;
		node->data = t;
		if (m_tail == nullptr)
		{
			m_head->next = node;
			node->previous = m_head;
			m_tail = node;
		}
		else
		{
			node->next = m_head->next;
			m_head->next = m_node;
			node->next->previous = node;
			node->previous = m_head;
		}
		m_size++;
		return *this;
	}

	template<typename T>
	Queue<T>& MContainer::Queue<T>::pushFront(T&& t) noexcept
	{
		assert(m_size + 1 <= m_maxSize);
		NodeT * node = new NodeT;
		node->data = std::move(t);
		if (m_tail == nullptr)
		{
			m_head->next = node;
			node->previous = m_head;
			m_tail = node;
		}
		else
		{
			node->next = m_head->next;
			m_head->next = node;
			node->next->previous = node;
			node->previous = m_head;
		}
		m_size++;
		return *this;
	}

	template<typename T>
	T MContainer::Queue<T>::popBack()
	{
		_throw(m_size == 0);

		NodeT *ptr = m_tail;
		T t = ptr->data;

		if (ptr->previous == m_head)
		{
			m_tail = nullptr;
			m_head->next = nullptr;
		}
		else
		{
			m_tail = m_tail->previous;
			m_tail->next = nullptr;
		}
		delete ptr;
		m_size--;
		return t;
	}

	template<typename T>
	T MContainer::Queue<T>::popFront()
	{
		_throw(m_size == 0);

		NodeT * ptr = m_head->next;
		T t = ptr->data;

		if (ptr == m_tail)
		{
			m_head->next = nullptr;
			m_tail = nullptr;
		}
		else
		{
			m_head->next = ptr->next;
			ptr->next->previous = m_head;
		}

		delete ptr;
		m_size--;
		return t;
	}

	template<typename T>
	T& MContainer::Queue<T>::head()
	{
		_throw(m_size == 0);
		return m_head->next->data;
	}

	template<typename T>
	T& MContainer::Queue<T>::tail()
	{
		_throw(m_size == 0);
		return m_tail->data;
	}

	template<typename T>
	const T& MContainer::Queue<T>::at(int pos)
	{
		_throw(pos >= m_size);
		NodeT * ptr = m_head->next;

		while (pos != 0)
		{
			ptr = ptr->next;
			pos--;
		}

		return ptr->data;
	}

	template<typename T>
	void MContainer::Queue<T>::clear() noexcept
	{
		NodeT *ptr = m_head->next;
		while (ptr != nullptr)
		{
			NodeT * node = ptr;
			ptr = ptr->next;
			delete node;
		}
		m_tail = nullptr;
		m_size = 0;
	}
单端队列
template<typename T>
	T MContainer::SQueue<T>::dequeue()
	{
		return Queue<T>::popFront();
	}

	template<typename T>
	SQueue<T>& MContainer::SQueue<T>::enqueue(const T& t) noexcept
	{
		Queue<T>::pushBack(t);
		return *this;
	}

单端队列主要是隐藏了双端队列的一下接口


为学习数据结构编写,容器可能存在问题。有建议可以留言指出,谢谢。

GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pointer=NULL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值