前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >队列的深度解析:链式队列的实现

队列的深度解析:链式队列的实现

作者头像
平凡之路.
发布2024-10-09 15:09:00
1250
发布2024-10-09 15:09:00
举报
文章被收录于专栏:学习

引言

队列是一种广泛应用于计算机科学的数据结构,具有先进先出FIFO)的特性。在许多实际应用中,例如任务调度、缓冲区管理等,队列扮演着重要角色。本文将详细介绍队列的基本概念,并通过链表实现一个简单的队列。

一、基本概念

1.1定义

队列是一种线性数据结构,遵循先进先出(FIFO,First In First Out)的原则。这意味着第一个被插入的元素是第一个被移除的元素。队列模拟了排队现象,新来的人不断加入队列尾部,而位于队列头部的人逐个离开。

如下图所示,我们将队列头部称为“队首”,尾部称为“队尾”,将把元素加入队尾的操作称为“入队”,删除队首元素的操作称为“出队”。

1.2基本操作

队列的主要操作包括:

  • 入队(Push):将一个元素添加到队列的尾部。
  • 出队(Pop):移从队列的头部移除并返回一个元素。
  • 取队首元素(Front):返回队首的元素,但不删除它。
  • 取队尾元素(Back):返回队尾的元素,但不删除它。
  • 队列判空(isEmpty):判断队列中是否有元素。
  • 获取队列长度(Size):获取队列中有效元素个数。

1.3队列的特点 

队列的特点包括: 先进先出(FIFO):最先进入的元素最先被移除。 操作限制:只能在队列的头部出队,在尾部入队。 队首元素:队首是当前可以访问和移除的元素。 空队列:队列为空时无法进行出队操作。 动态大小:可以根据需要扩展或收缩。

三、链式队列的实现 

1.链表节点的定义

首先,我们定义一个链表节点结构:

代码语言:javascript
复制
typedef int DataType;
//定义节点结构体
typedef struct Node
{
	DataType data;//数据域
	struct Node* next;//指针域
}Node;

2.队列结构的定义

然后,我们定义队列结构,包含队头、队尾指针以及队列长度:

代码语言:javascript
复制
//定义队列结构体
typedef struct Queue
{
	Node* phead;//队头
	Node* ptail;//队尾
	int size;//队列长度
}QU;

3.基本操作 

(1).初始化队列

代码语言:javascript
复制
//初始化队列 
void QueueInit(QU* p)
{
	assert(p);
	p->phead = p->ptail = NULL;
	p->size = 0;
}

(2).入队

代码语言:javascript
复制
//创建节点
//Node* CreateNode(DataType x)
//{
//	Node* newnode = (Node*)malloc(sizeof(Node));
//	if (newnode == NULL) {
//		perror("malloc fail");
//		exit(1);
//	}
//	newnode->data = x;
//	newnode->next = NULL;
//	return newnode;
//}

//入队列,队尾
void QueuePush(QU* p, DataType x)
{
	assert(p);
	Node* newnode = CreateNode(x);
	if (p->phead == NULL)//队列为空
	{
		p->phead = p->ptail = newnode;
	}
	else//队列不为空
	{
		p->ptail->next = newnode;
		p->ptail = newnode;
	}
	++p->size;
}

(3).队列判空

代码语言:javascript
复制
//队列判空 
bool QueueEmpty(QU* p)
{
	assert(p);
	return p->phead == NULL;
}

(4).出队 

代码语言:javascript
复制
//出队列,队头 
void QueuePop(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列为空不能出队
	if (p->phead == p->ptail)//只有一个元素时
	{
		free(p->phead);
		p->phead = p->ptail = NULL;
	}
	else
	{
		Node* del = p->phead;
		p->phead = p->phead->next;
		free(del);
	}
	--p->size;
}

(5).取队首元素

代码语言:javascript
复制
//取队头数据 
DataType QueueFront(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列不能为空
	return p->phead->data;
}

(6).取队尾元素 

代码语言:javascript
复制
//取队尾数据 
DataType QueueBack(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列不能为空
	return p->ptail->data;
}

(7).获取队列长度

代码语言:javascript
复制
//队列长度
int QueueSize(QU* p)
{
	assert(p);
	return p->size;
}

(8).销毁队列 

代码语言:javascript
复制
//销毁队列 
void QueueDestroy(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列不能为空
	Node* pcur = p->phead;
	while (pcur)
	{
		Node* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	p->phead = p->ptail = NULL;
	p->size = 0;
}

四、完整代码 

Queue.h

该部分主要包括函数的声明、以及头文件的引用

代码语言:javascript
复制
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int DataType;
//定义节点结构体
typedef struct Node
{
	DataType data;//数据域
	struct Node* next;//指针域
}Node;
//定义队列结构体
typedef struct Queue
{
	Node* phead;//队头
	Node* ptail;//队尾
	int size;//队列长度
}QU;
//初始化队列 
void QueueInit(QU* p); 
//入队列,队尾
void QueuePush(QU* p, DataType x);
//队列判空 
bool QueueEmpty(QU* p);
//出队列,队头 
void QueuePop(QU* p);
//取队头数据 
DataType QueueFront(QU* p);
//取队尾数据 
DataType QueueBack(QU* p);
//队列长度
int QueueSize(QU* p);
//销毁队列 
void QueueDestroy(QU* p);

Queue.c

该部分主要包括函数的定义 

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
//初始化队列 
void QueueInit(QU* p)
{
	assert(p);
	p->phead = p->ptail = NULL;
	p->size = 0;
}

//创建节点
Node* CreateNode(DataType x)
{
	Node* newnode = (Node*)malloc(sizeof(Node));
	if (newnode == NULL) {
		perror("malloc fail");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

//入队列,队尾
void QueuePush(QU* p, DataType x)
{
	assert(p);
	Node* newnode = CreateNode(x);
	if (p->phead == NULL)//队列为空
	{
		p->phead = p->ptail = newnode;
	}
	else//队列不为空
	{
		p->ptail->next = newnode;
		p->ptail = newnode;
	}
	++p->size;
}
//队列判空 
bool QueueEmpty(QU* p)
{
	assert(p);
	return p->phead == NULL;
}
//出队列,队头 
void QueuePop(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列为空不能出队
	if (p->phead == p->ptail)//只有一个元素时
	{
		free(p->phead);
		p->phead = p->ptail = NULL;
	}
	else
	{
		Node* del = p->phead;
		p->phead = p->phead->next;
		free(del);
	}
	--p->size;
}
//取队头数据 
DataType QueueFront(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列不能为空
	return p->phead->data;
}
//取队尾数据 
DataType QueueBack(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列不能为空
	return p->ptail->data;
}
//队列长度
int QueueSize(QU* p)
{
	assert(p);
	return p->size;
}
//销毁队列 
void QueueDestroy(QU* p)
{
	assert(p);
	assert(!QueueEmpty(p));//队列不能为空
	Node* pcur = p->phead;
	while (pcur)
	{
		Node* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	p->phead = p->ptail = NULL;
	p->size = 0;
}

 main.c

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
void test()
{
	QU qu;
	QueueInit(&qu);
	QueuePush(&qu, 1);
	QueuePush(&qu, 2);
	QueuePush(&qu, 3);
	QueuePush(&qu, 4);
	QueuePop(&qu);
	printf("head:%d\n", QueueFront(&qu));
	printf("back:%d\n", QueueBack(&qu));
	printf("size:%d\n", QueueSize(&qu));
}
int main()
{
	test();
	return 0;
}

五、总结

在本次博客中,我们实现了一个基本的队列数据结构,涵盖了以下几个关键功能:

  1. 初始化队列:创建一个空队列,准备进行后续操作。
  2. 入队:实现了在队尾添加新元素的功能,确保队列能够动态扩展。
  3. 队列判空:提供了检查队列是否为空的方法,便于在操作前判断队列状态。
  4. 出队:实现了从队首移除元素的功能,遵循先进先出的原则。
  5. 取队首元素:能够访问当前队首元素,但不移除它,方便查看下一个处理的元素。
  6. 取队尾元素:允许访问队尾元素,虽然不常见,但在某些场景中有其用途。
  7. 获取队列长度:实现了获取当前队列中元素数量的功能,便于管理和监控队列状态。
  8. 销毁队列:提供了清理队列资源的方法,防止内存泄漏。

通过实现这些基本操作,我们展示了队列的基本特性和使用方法,为理解队列在实际应用中的重要性奠定了基础。队列作为一种重要的数据结构,在任务调度、资源管理等多个领域都有广泛应用。希望这篇博客能帮助你更好地理解和使用队列。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-09-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 一、基本概念
    • 1.1定义
      • 1.2基本操作
        • 1.3队列的特点 
        • 三、链式队列的实现 
          • 1.链表节点的定义
            • 2.队列结构的定义
              • 3.基本操作 
              • 四、完整代码 
              • 五、总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档