第94篇 C++数据结构(四)队列

本文详细介绍了C++中队列数据结构的实现,包括使用链表存储结构,定义节点,以及实现队列的基本操作如入队、出队、队头访问、判断队列是否为空和获取队列大小。通过测试代码展示了队列功能的正确性,包括构造队列、插入元素、访问队头、拷贝队列、弹出元素和清空队列等操作。
摘要由CSDN通过智能技术生成

1.队列简介

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。

1.队列的存储结构

(1)数组:队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针:队头指针 front指向队头元素,队尾指针 rear 指向队尾元素的下一个位置。
(2)链表:队列的链式存储结构表示为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表,只不过它只能尾进头出而已。

2.节点

链式存储个人感觉比较方便,实现的也是链式存储方式,再次定义节点。

template <typename _dataType>
struct QueueNode
{
	using _QueueNodePtr = QueueNode*;

	_dataType m_value;
	_QueueNodePtr m_next;

	QueueNode() : m_value(_dataType()), m_next(nullptr) {}
	QueueNode(_dataType value) : m_value(value), m_next(nullptr) {}
	QueueNode(_dataType value, _QueueNodePtr next) : m_value(value), m_next(next) {}
};

3.实现

3.1.变量

变量名类型属性说明
m_front_QueueNodePtr公有队头
m_tail_QueueNodePtr公有队尾
m_lensize_t公有数据个数

3.2.方法

方法名返回类型参数属性说明
Queue()--公有缺省构造
Queue()-const Queue& q公有拷贝构造
operator = ()Queue&const Queue& q公有=运算符重载
push()void_dataType value公有入队
pop()void-公有出队
top()_dataType&-公有队头访问
empty()bool-公有判断队列是否为空
size()size_t-公有队列里面数据个数

4.测试

4.1.测试代码

#include <iostream>

#include "Queue.h"

void queueTest();

int main()
{
	queueTest();

	return 0;
}

void queueTest()
{
	std::cout << "\n构造:" << std::endl;
	Queue<int> q;

	std::cout << "\n数据个数:" << q.size() << std::endl;

	std::cout << "\nempty:" << std::endl;
	if (q.empty()) {
		std::cout << "q is empty!" << std::endl;
	}
	else {
		std::cout << "q isn't empty!" << std::endl;
	}

	std::cout << "\npush(7)" << std::endl;
	q.push(7);
	std::cout << "\n数据个数:" << q.size() << std::endl;
	std::cout << "front = " << q.front() << std::endl;

	std::cout << "\npush:1,2,3,4,5,6" << std::endl;
	int num = 1;
	while (num < 7) {
		q.push(num++);
	}
	std::cout << "\n数据个数:" << q.size() << std::endl;
	std::cout << "front = " << q.front() << std::endl;

	Queue<int> qt = q;
	while (!qt.empty()) {
		std::cout << qt.front() << ", ";
		qt.pop();
	}

	std::cout << "\nempty:" << std::endl;
	if (q.empty()) {
		std::cout << "q is empty!" << std::endl;
	}
	else {
		std::cout << "q isn't empty!" << std::endl;
	}

	std::cout << "\npop" << std::endl;
	q.pop();
	std::cout << "\n数据个数:" << q.size() << std::endl;
	std::cout << "front = " << q.front() << std::endl;

	std::cout << "\n清空队列:" << std::endl;
	while (!q.empty()) {
		q.pop();
	}

	std::cout << "\n数据个数:" << q.size() << std::endl;
	std::cout << "\nempty:" << std::endl;
	if (q.empty()) {
		std::cout << "q is empty!" << std::endl;
	}
	else {
		std::cout << "q isn't empty!" << std::endl;
	}
}

4.2.输出结果

构造:

数据个数:0

empty:
q is empty!

push(7)

数据个数:1
front = 7

push:1,2,3,4,5,6

数据个数:7
front = 7
7, 1, 2, 3, 4, 5, 6,
empty:
q isn't empty!

pop

数据个数:6
front = 1

清空队列:

数据个数:0

empty:
q is empty!

5.实现代码

#pragma once
#ifndef _QUEUE_H_
#define _QUEUW_H_

#include <cassert>

template <typename _dataType>
struct QueueNode
{
	using _QueueNodePtr = QueueNode*;

	_dataType m_value;
	_QueueNodePtr m_next;

	QueueNode() : m_value(_dataType()), m_next(nullptr) {}
	QueueNode(_dataType value) : m_value(value), m_next(nullptr) {}
	QueueNode(_dataType value, _QueueNodePtr next) : m_value(value), m_next(next) {}
};

template <typename _dataType>
class Queue
{
	using _QueueNodePtr = QueueNode<_dataType>*;
public:
	Queue() : m_front(nullptr), m_tail(nullptr), m_len(0) {}

	Queue(const Queue& q)
	{
		if (q.m_front) {
			m_front = new QueueNode<_dataType>(q.m_front->m_value);
			m_tail = m_front;
			_QueueNodePtr front = q.m_front->m_next;
			while (front) {
				m_tail->m_next = new QueueNode<_dataType>(front->m_value);
				m_tail = m_tail->m_next;
				front = front->m_next;
			}

			m_len = q.m_len;
		}
		else {
			m_front = nullptr;
			m_tail = nullptr;
			m_len = 0;
		}
	}

	Queue& operator = (const Queue& q)
	{
		while (this->m_front) {
			this->pop();
		}

		if (q.m_front) {
			m_front = new QueueNode<_dataType>(q.m_front->m_value);
			m_tail = m_front;
			_QueueNodePtr front = q.m_front->m_next;
			while (front) {
				m_tail->m_next = new QueueNode<_dataType>(front->m_value);
				m_tail = m_tail->m_next;
				front = front->m_next;
			}

			m_len = q.m_len;
		}
		else {
			m_front = nullptr;
			m_tail = nullptr;
			m_len = 0;
		}

		return *this;
	}

	void push(_dataType value)
	{
		if (m_front == nullptr) {
			m_front = new QueueNode<_dataType>(value);
			m_tail = m_front;
		}
		else {
			m_tail->m_next = new QueueNode<_dataType>(value);
			m_tail = m_tail->m_next;
		}

		m_len++;
	}

	void pop()
	{
		assert(m_front);

		if (m_front == m_tail) {
			delete m_front;
			m_front = nullptr;
			m_tail = nullptr;
		}
		else {
			_QueueNodePtr front = m_front;
			m_front = m_front->m_next;

			delete front;
			front = nullptr;
		}

		m_len--;
	}

	_dataType& front()
	{
		assert(m_front);

		return m_front->m_value;
	}

	size_t size()
	{
		return m_len;
	}

	bool empty()
	{
		return m_front == nullptr;
	}

private:
	_QueueNodePtr m_front;
	_QueueNodePtr m_tail;
	size_t m_len;
};

#endif // _QUEUE_H_

6.总结

只有实现,并没有详细介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大唐不良猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值