C++数据结构之队列详解

这篇具有很好参考价值的文章主要介绍了C++数据结构之队列详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.队列的简述

队列也是一种收限制的线性表,其特点是在一端进行插入的时,再另一端进行出队列的操作(删除操作)。把允许插
入操作的一端叫做队尾,允许删除操作的一端叫做队头。队列就像超市排队结账的人群,排在收银台一端的优先结账
离开,后面的依次排队并一直收银台前进,每出队列一个,向前走一步。
向队列插入元素称为入队,从队列中删除元素称为出队。不包含任何数据的队列称为空队列,队列也被称为先进先出
(First In First Out:FIFO)的线性表,换句话说,插入数据只能在队尾进行,删除操作只能在队头进行。
(后面还会有特殊情况:双端队列)

c++队列,数据结构,c++
c++队列,数据结构,c++
队头填充进四个元素

2.队列的基本顺序存储代码:

#define MaxSize 10//队列的初始化尺寸

template<typename T>
class SeqQueue 
{
public:
	SeqQueue();
	~SeqQueue();

public:
	bool EnQueue(const T& e);//入队列
	bool DeQueue(T& e);//出队列
	bool GetHead(T& e);//读取头元素
	void ClearQueue();//清空队列
	void DispList();//输出顺序队列中的所有元素
	int ListLength();//获取队列长度(元素个数)
	bool IsEmpty();//判断队列是否为空
	bool IsFull();//判断队列是否已满

private:
	T* m_data;
	int m_front;//队头指针(数组下标)
	int m_rear;//队尾指针(数组下标),允许出队的那一端
};

template<typename T>
SeqQueue<T>::SeqQueue() 
{
	m_data = new T[MaxSize];
	m_front = 0;
	m_rear = 0;
}

template<typename T>
SeqQueue<T>::~SeqQueue() 
{
	delete[] m_data;
}

template<typename T>
bool SeqQueue<T>::EnQueue(const T& e)
{
	if (IsFull() == true) 
	{
		cout << "队列满了,不能再进行入队列操作了!" << endl;
		return false;
	}
	m_data[m_rear] = e;
	m_rear++;
	return true;
}

template<typename T>
bool SeqQueue<T>::DeQueue(T& e)
{
	if (IsEmpty() == true) 
	{
		cout << "当前队列为空,不能进行出队列操作!" << endl;
		return false;
	}
	e = m_data[m_front];
	m_front++;
	return true;
}

template<typename T>
bool SeqQueue<T>::GetHead(T& e) 
{
	if (IsEmpty() == true) 
	{
		cout << "队列为空,无法进行获取头元素操作!" << endl;
		return false;
	}
	e = m_data[m_front];
	return true;
}

template<typename T>
void SeqQueue<T>::DispList() 
{
	for (int i = 0; i < m_rear;i++) 
	{
		cout << m_data[i] << " ";
	}
	cout << endl;
}

template<typename T>
int SeqQueue<T>::ListLength()
{
	return m_rear - m_front;
}

template<typename T>
bool SeqQueue<T>::IsEmpty() 
{
	if (m_front == m_rear) 
	{
		return true;
	}
	return false;
}

template<typename T>
bool SeqQueue<T>::IsFull() 
{
	if (m_rear >= _Maximum) 
	{
		return true;
	}
	return false;
}

template<typename T>
void SeqQueue<T>::ClearQueue() 
{
	m_rear = m_front = 0;
}

c++队列,数据结构,c++

此时思考一个问题,当删除元素时(元素出队列时)会出现假饱和的情况,如上图m_data[0]和m_data[1]再进行出队列操作之后,这两个位置可以容纳新的元素,但m_rear没有回到原本的m_data[0]位置,因此需要引入一个新的队列结构,环形队列,m_rear这个位置可以从0到9再到0,周而复始不停的重复,保存的数据像在一个环状空间一样,这种头尾相连的队列结构就叫循环队列。
c++队列,数据结构,c++

3.优化普通队列,成为可以循环接受数据的循环队列

循环队列代码如下:

#define MaxSize 10

template<typename T>
class RoundQueue
{
public:
	RoundQueue();
	~RoundQueue();

public:
	bool EnQueue(const T& e);//入队列
	bool DeQueue(T& e);//出队列
	bool GetHead(T& e);//读取头元素
	void ClearQueue();//清空队列
	void DispList();//输出顺序队列中的所有元素
	int ListLength();//获取队列长度(元素个数)
	bool IsEmpty();//判断队列是否为空
	bool IsFull();//判断队列是否已满

private:
	T m_data;
	int m_front;//队头指针(数组下标)
	int m_rear;//队尾指针(数组下标),允许出队的那一端
	char m_tag;
};

template<typename T>
RoundQueue<T>::RoundQueue()
{
	m_data = new T[MaxSize];
	m_front = 0;
	m_rear = 0;
	m_tag = 0;//加入表示栈是否满的状态
}

template<typename T>
RoundQueue<T>::~RoundQueue()
{
	delete[] m_data;
}

template<typename  T>
bool RoundQueue<T>::EnQueue(const T& e) 
{
	if (IsFull () == true)
	{
		cout << "队列满了,不能再进行入队列操作了!" << endl;
		return false;
	}
	m_tag = 1;
	m_data[m_rear] = e;
	m_rear = (m_rear + 1) % MaxSize;
	return true;
}

template<typename T>
bool RoundQueue<T>::DeQueue(T& e) 
{
	if (IsEmpty() == true)
	{
		cout << "当前队列为空,不能进行出队列操作!" << endl;
		return false;
	}
	m_tag = 0;
	e = m_data[m_front];
	m_front = (m_front + 1) % MaxSize;
	return true;
}

template<typename T>
bool RoundQueue<T>::GetHead(T& e)
{
	if (IsEmpty() == true)
	{
		cout << "队列为空,无法进行获取头元素操作!" << endl;
		return false;
	}
	e = m_data[m_front];
	return true;
}

template<typename T>
void RoundQueue<T>::DispList()
{
	for (int i = m_front;i != m_rear)
	{
		cout << m_data[i] << " ";
		i = (i + 1) % MaxSize;
	}
	cout << endl;
}

template<typename T>
bool RoundQueue<T>::IsFull()
{
	if (m_rear == m_front && tag == 0)
	{
		return true;
	}
	return false;
}

template<typename T>
int RoundQueue<T>::ListLength()
{
	return (m_rear + MaxSize - m_front) % MaxSize;
}

template<typename T>
bool RoundQueue<T>::IsEmpty()
{
	if (m_front == m_rear && tag == 0)
	{
		return true;
	}
	return false;
}

template<typename T>
void RoundQueue<T>::ClearQueue()
{
	m_rear = m_front = m_tag = 0;
}

循环队列队列满的情况,如下图:
c++队列,数据结构,c++

4.队列的链式结构实现

和前面所有的数据结构一样,队列也有链式结构

空队列的情况:
c++队列,数据结构,c++
插入两个元素之后的队列:
c++队列,数据结构,c++

实现代码如下图所示:

template<typename T>
struct QueueNode 
{
	T data;//数据域
	QueueNode<T>* next;//指针域,指向下一个节点
};

template<typename T>
class LinkQueue 
{
public:
	LinkQueue();
	~LinkQueue();

public:
	bool EnQueue(const T& e);//入队
	bool DeQueue(T& e);//出队
	bool GetHead(T& e);//读取头元素
	void DispList();//输出链式队列中的所有元素
	int ListLength();//获取链式队列的长度(链式表元素个数)
	bool IsEmpty();//判断链式队列是否为空

private:
	QueueNode<T>* m_front;//头指针,这一端允许出队(删除)
	QueueNode<T>* m_rear;//尾指针记录入队
	int m_length;
};

template<typename T>
LinkQueue<T>::LinkQueue() 
{
	m_front = new QueueNode<T>;
	m_front->next = nullptr;
	m_rear = m_front;
	m_length = 0;
}

template<typename T>
LinkQueue<T>::~LinkQueue() 
{
	QueueNode<T>* pnode = m_front->next;
	QueueNode<T>* ptmp;
	while (pnode != nullptr)
	{
		ptmp = pnode;
		pnode = pnode->next;
		delete ptmp;
	}
	delete m_front;
	m_front = m_rear = nullptr;
	m_length = 0;
}

template<typename T>
bool LinkQueue<T>::EnQueue(const T& e) 
{
	QueueNode<T>* node = new QueueNode<T>;
	node->data = e;
	node->next = nullptr;

	m_rear->next = node;//新节点插入到头指针之后
	m_rear = node;//更新队尾指针的位置
	m_length++;
	return true;
}

template<typename T>
bool LinkQueue<T>::DeQueue(T& e) 
{
	if (IsEmpty() == true) 
	{
		cout << "当前链式队列为空,无法进行出队列操作!" << endl;
		return false;
	}
	QueueNode<T>* p_willdel = m_front->next;
	e = p_willdel->data;
	m_front->next = p_willdel->next;
	if (m_rear == p_willdel) //队列中只有一个元素,删除之后,m_rear和m_front相连
	{
		m_rear = m_front;
	}
	delete p_willdel;
	m_length--;
	return true;
}

template<typename T>
void LinkQueue<T>::DispList() 
{
	QueueNode<T>* p = m_front->next;
	while (p != nullptr) 
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

template<typename T>
int LinkQueue<T>::ListLength() 
{
	return m_length;
}

template<typename T>
bool LinkQueue<T>::IsEmpty() 
{
	if (m_front == m_rear) 
	{
		return true;
	}
	return false;
}

5.双端队列

前面的几种队列都可以看成普通的队列,还有一种变形的队列-双端队列。双端队列就是允许两端插入和删除数据。STL中提供的名字叫做deque的容器,就是一个典型的双端队列。双端队列的存取如图所示:

c++队列,数据结构,c++
也可以对双端队列进行一系列的限制,可以有输入受限的的双端队列和输出受限的双端队列,如图为输入受限的双端队列,只能一端输入,两端输出:
c++队列,数据结构,c++
也可也一端输出,两端输入的双端队列,如图:
c++队列,数据结构,c++
代码实现如下:文章来源地址https://www.toymoban.com/news/detail-752488.html

// 节点
template<class T>
class Node
{
public:
	T data;
	Node<T> *left;
	Node<T> *right;
	Node() {
		data= 0;
		left = right = nullptr;
	}
	Node(T n) {
		data= n;
		left = right = nullptr;
	}
};
// 双端队列
template<class T>
class double_ended_queue {
public:
	Node<T>*queue_left, *queue_right;
	int num;
	int size;
	
	double_ended_queue() {
		queue_left=queue_right = nullptr;
		num = 0;
		size = 10;
	}
	
	void IsEmpty();
	void IsFull();
	void AddLeft(T);
	void AddRight(T);
	void DeleteLeft();
	void DeleteRight();
	void Print();
};

template<class T>
void double_ended_queue<T>::IsEmpty() {
	num == 0 ? cout << "YES" << endl : cout << "NO" << endl;
}

template<class T>
void double_ended_queue<T>::IsFull() {
	num == size ? cout << "YES" << endl : cout << "NO" << endl;
}

template<class T>
void double_ended_queue<T>::Print() {
	if (num == 0)
	{
		cout << "EMPTY" << endl;
		return;
	}
	Node<T>*p = queue_left;
	for (int i = 0; i < num-1; i++) {
		cout << p->data << " ";
			p = p->right;
	}
	cout << p->data << endl;
}

template<class T>
void double_ended_queue<T>::AddLeft(T n) {
	Node<T>*p = new Node<T>(n);
	if (num == 0)
	{
		queue_left =queue_right=p;
		queue_left->left =queue_left->right=nullptr;
		num++;
	}
	else{
		if (num == size)
		{
			cout << "FULL  ";
			Print();
			return;
		}
		queue_left->left = p;
		p->right = queue_left;
		queue_left = queue_left->left;
		num++;
	}
	Print();
}

template<class T>
void double_ended_queue<T>::AddRight(T n) {
	Node<T>*p = new Node<T>(n);
	if (num == 0)
	{
		queue_left = queue_right = p;
		queue_right->left = queue_right->right = nullptr;
		num++;
	}
	else {
		if (num == size)
		{
			cout << "FULL  " ;
			Print();
			return;
		}
		queue_right->right = p;
		p->left = queue_right;
		queue_right = queue_right->right;
		num++;
	}
	Print();
}

template<class T>
void double_ended_queue<T>::DeleteLeft() {
	if (num == 0) {
		cout << "EMPTY" << endl;
		return;
	}
	Node<T>*p = queue_left->right;
	delete queue_left;
	queue_left = p;
	num--;
	Print();
}

到了这里,关于C++数据结构之队列详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c++实现数据结构栈和队列

    1、栈 头文件 源文件 主函数 2、循环队列 头文件 源文件 主函数 3、思维导图

    2024年02月08日
    浏览(40)
  • C++中的常见数据结构 --- 队列、栈、列表

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 队列、栈、列表是其中三个最为基础和常用的数据结构,它们在编程的世界中被广泛应用,为算法和数据处理提供了不可或缺的支持。今天来简单的介绍一下!以及他们在C++中的简单用法! 队列是一种常见

    2024年01月22日
    浏览(49)
  • 数据结构03:栈、队列和数组 队习题01[C++]

       考研笔记整理~🥝🥝 之前的博文链接在此:数据结构03:栈、队列和数组_-CSDN博客~🥝🥝 本篇作为链表的代码补充,供小伙伴们参考~🥝🥝 第1版:王道书的课后习题~🧩🧩 编辑: 梅头脑🌸 参考用书: 王道考研《2025年 数据结构考研复习指导》 目录 🧵01 不牺牲存储单

    2024年04月13日
    浏览(30)
  • 从0开始学C++ 第二十八课 数据结构深入 - 栈和队列

    第二十八课:数据结构深入 - 栈和队列 学习目标: 理解栈(Stack)的基本概念和特性。 掌握队列(Queue)的基本概念和特性。 学会在C++中使用栈和队列。 了解栈和队列的典型应用场景。 学习内容: 栈(Stack) 概念:栈是一种后进先出(LIFO, Last In First Out)的数据结构,元素

    2024年01月23日
    浏览(47)
  • 数据结构与算法—顺序表、链接表、顺序栈、链接栈、顺序队列、链接队列的C++代码实现

    线性表是一种常见的数据结构,具有以下几个特点: 元素的有限序列:线性表是由有限个元素组成的有序序列,每个元素的位置都是唯一确定的。 线性结构:线性表中的元素只有一个前驱和一个后继,除第一个和最后一个元素外,每个元素都有一个前驱和一个后继。 线性表

    2024年02月08日
    浏览(41)
  • 【C++】【数据结构】循环队列的基本操作(初始化、入队、出队、取队头元素、遍历输出队列、求队列长度)顺序队列的算法实现【附全代码】

    使用c++完成数据结构循环队列的基本操作,包括(初始化、入队、出队、取队头元素、遍历输出队列、求队列长度等),可直接编译运行。 队列 又称为 “先进先出” (FIFO)线性表。限定插入操作只能在队尾进行,而删除操作只能在队首进行。 循环队列 ——采用 顺序存储结构

    2023年04月16日
    浏览(53)
  • C++数据结构之链表(详解)

    主要参考文章地址 01.链表基础知识 | 算法通关手册 (itcharge.cn)) 本次内容是对链表的总结,可以看了上面的文章之后。 在看我下面的内容,做一个简短的复习,且本内容的代码均用C++实现,而参考资料的代码则为python。 每一个标题都有一个完整的链接,也可以点击下面的链

    2024年02月15日
    浏览(76)
  • 手撕哈希表(HashTable)——C++高阶数据结构详解

    小编是双非本科大一菜鸟不赘述,欢迎米娜桑来指点江山哦(QQ:1319365055) 🎉🎉非科班转码社区诚邀您入驻🎉🎉 小伙伴们,打码路上一路向北,彼岸之前皆是疾苦 一个人的单打独斗不如一群人的砥砺前行 这是我和梦想合伙人组建的社区,诚邀各位有志之士的加入!! 社

    2023年04月08日
    浏览(37)
  • 【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题

    更多算法例题链接: 【数据结构与算法】递推法和递归法解题(递归递推算法典型例题) 什么是迭代器(iterator) 迭代器(iterator)的定义: 迭代器是一种检查容器内元素并遍历元素的数据类型。 迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。 容器

    2024年04月14日
    浏览(50)
  • 【数据结构】队列详解

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:数据结构 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的特性。

    2024年02月05日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包