【数据结构】C++语言实现队列(详细解读)

【数据结构】C++语言实现队列(详细解读)

码农世界 2024-05-27 后端 92 次浏览 0个评论

【数据结构】C++语言实现队列(详细解读)

 c语言中的小小白-CSDN博客c语言中的小小白关注算法,c++,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm=1001.2014.3001.5343

【数据结构】C++语言实现队列(详细解读)

给大家分享一句我很喜欢我话:

知不足而奋进,望远山而前行!!!

铁铁们,成功的路上必然是孤独且艰难的,但是我们不可以放弃,远山就在前方,但我们能力仍然不足,所有我们更要奋进前行!!!

今天我们更新了队列内容,

🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

什么是队列?

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(head)进行删除操作,而在表的后端(tail)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

这个队列就可以理解成我们平时的排队,先进入的先出去,与我们之前实现的先进后出的栈相反。

用什么来实现栈?

再把上次的图拿出来,我们看看是用线性表来实现队列,还是链表比较好❓

【数据结构】C++语言实现队列(详细解读)

由于我们队列中有多少元素不确定,为了方便,我们使用链表,可以做到需要就直接申请,还有一点就是队列是先进先出,顺序固定,不需要随机访问。所以我们这里实现队列使用链表。

队列的实现

头文件:

#include
#include
#include
#include
#include

定义结构体:

typedef int QDataType;
typedef struct QueueNode//队列的元素节点
{
	struct QueueNode* next;
	QDataType val;
}QNode;
typedef struct Queue//队列
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

函数声明:

//初始化
void QueueInit(Queue* pq);
//队尾插入
void QueuePush(Queue* pq, QDataType x);
//头删
void QueuePop(Queue* pq);
//获取长度
int QueueSize(Queue* pq);
//队列的销毁
void QueueDestroy(Queue* pq);
//取出队首元素
QDataType QueueFront(Queue* pq);
//取出队尾元素
QDataType QueueBack(Queue* pq);
//判断是否为空
bool QueueEmpty(Queue* pq);

函数的实现:

队列的初始化:

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

初始化还是比较简单的,就是令这个头和尾都为NULL,size=0。

队列的尾插:

//尾插
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc failed!");
		exit(0);
	}
	newnode->next = NULL;
	newnode->val = x;
	
	if (pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail = pq->ptail->next = newnode;
	}
	pq->size++;
}

尾插这里我们要注意分为两种情况,一种就是此时这个队列还为空队列,这时就要令ptail和phead都为newnode,然后若不是,那么我们就只令ptail的下一个点等于newnode,然后ptail指向下一个点。

队列的头删:

//头删
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->size != 0);
	//一个节点,防止出现野指针
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
		pq->size--;
	}
}

头删我们这里也要注意,因为我们这个队列玩意只有一个点,那么我们删除之后可能就会造成ptail为野指针的情况,所以我们这里也要分情况:一种就是如果phead指向NULL,即只有一个节点,所以我们就要free掉phead的同时,还要将两个都置为NULL,另一种情况就只需要关注phead,操作完之后将phead指向下一个点。

获取队列长队:

//获取长度
int QueueSize(Queue* pq)
{
	assert(pq);
	
	return pq->size;
}

这里就是我们前面创建对列要加一个size的原因,这样我们就可以方便的知道队列的大小,否则每次想得到队列的大小都要重新计算一遍,浪费更多的时间。

队列的销毁:

//队列的销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur); 
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
}

队列的销毁也没什么好说的,就是创建一个新的队列,然后循环不断free每一个队列点。

获取队尾元素和队首元素:

//获取队首元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead && pq->ptail);//防止为空
	return pq->phead->val;
}
//获取队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->phead && pq->ptail);
	
	return pq->ptail->val;
}

这个就是先断言一下,然后直接返回对应的值即可。

判断是否为空:

//判断是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->ptail == NULL;
}

这里直接用bool来判断,是就返回true,否则返回false。

完整代码:

Queue.h

#pragma once
#include
#include
#include
#include
#include
using namespace std;
typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType val;
}QNode;
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;
//初始化
void QueueInit(Queue* pq);
//队尾插入
void QueuePush(Queue* pq, QDataType x);
//头删
void QueuePop(Queue* pq);
//获取长度
int QueueSize(Queue* pq);
//队列的销毁
void QueueDestroy(Queue* pq);
//取出队首元素
QDataType QueueFront(Queue* pq);
//取出队尾元素
QDataType QueueBack(Queue* pq);
//判断是否为空
bool QueueEmpty(Queue* pq);

Queue.cpp:

#include"Queue.h"
//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}
//尾插
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc failed!");
		exit(0);
	}
	newnode->next = NULL;
	newnode->val = x;
	
	if (pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail = pq->ptail->next = newnode;
	}
	pq->size++;
}
//头删
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->size != 0);
	//一个节点,防止出现野指针
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
		pq->size--;
	}
}
//获取长度
int QueueSize(Queue* pq)
{
	assert(pq);
	
	return pq->size;
}
//队列的销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur); 
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
}
//获取队首元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead && pq->ptail);//防止为空
	return pq->phead->val;
}
//获取队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->phead && pq->ptail);
	
	return pq->ptail->val;
}

//判断是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->ptail == NULL;
}

test.cpp:

#include"Queue.h"
int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);
	QueuePop(&q);
	while (!QueueEmpty(&q))
	{
		cout << QueueFront(&q)< 

转载请注明来自码农世界,本文标题:《【数据结构】C++语言实现队列(详细解读)》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,92人围观)参与讨论

还没有评论,来说两句吧...

Top