【数据结构与算法】队列的实现

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

🌠作者:@阿亮joy.
🎆专栏:《数据结构与算法要啸着学》
🎇座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
【数据结构与算法】队列的实现


👉队列的概念及结构👈

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的原则

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

【数据结构与算法】队列的实现

队列的结构在生活中非常地常见,比如排队时的抽号机就是一个典型的队列结构。那队列如何实现呢?我们一起来看一下。

👉队列的实现👈

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些。因为如果使用数组的结构,出队列在数组头上出数据,需要挪动数据,时间复杂度为O(N),效率会比较低。

【数据结构与算法】队列的实现

Queue.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;

typedef struct Queue
{
	QNode* head; // 头指针
	QNode* tail; // 尾指针
	int size;    // 节点的个数
}Queue;

void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);

队列要实现的函数接口有:初始化队列、销毁队列、数据入队、数据出队、返回队头的数据、返回队尾的数据、判断队列是否为空以及队列中数据的个数。这些接口实现起来也不是很难,我们一起来看一下。

Queue.c

#include "Queue.h"

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}

	// 队列中没有节点
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}

	pq->size++;
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	// 队列中只有一个节点
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* del = pq->head;
		pq->head = pq->head->next;
		free(del);
		//del = NULL;
	}

	pq->size--;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
	//return pq->head == NULL && pq->tail == NULL;
}
int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

初始化队列

头指针和尾指针都指向空,队列元素个数初始化为0

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

销毁队列

利用while循环将申请的节点一一释放掉,然后头指针pq->head和尾指针pq->tail指向空,栈的数据个数置为 0pq->size = 0

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

数据入队

1.申请新的节点newnode newnode->data = x,newnode->next = NULL
2.数据入队:当pq->tail == NULL时,队列中没有节点,那么头指针和尾指针都赋值为newnode pq->head = pq->tail = newnode;当pq->tail != NULL时,队列中有节点,那么尾部链接上新节点newnode,然后newnode成为新的尾结点。
3.队列数据个数加一pq->size++

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}

	// 队列中没有节点
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}

	pq->size++;
}

数据出队

1.判断队列是否为空
2.数据出队:当pq->head->next == NULL时,队列中只有一个节点,释放该节点,头指针和尾指针都指向空;当pq->head->next != NULL时,释放让头指针指向当前节点的下一个节点,释放原来的头节点
3.队列数据个数减一pq->size--

【数据结构与算法】队列的实现

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	// 队列中只有一个节点
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* del = pq->head;
		pq->head = pq->head->next;
		free(del);
		//del = NULL;
	}

	pq->size--;
}

返回队头数据

先判断队列是否为空,不为空时,返回队头数据。

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

返回队尾数据

先判断队列是否为空,不为空时,返回队尾数据。

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

判断队列是否为空

判断队列是否为空有两种方式:1.判断pq->size等不等于 0;2.判断头指针pq->head和尾指针pq->tail是否等于空指针NULL

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
	//return pq->head == NULL && pq->tail == NULL;
}

队列中数据的个数

直接返回队列数据的个数pq->size

int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

Test.c

以下为测试函数接口的代码,大家可以参考一下。需要注意的是,打印队列中的数据是通过打印队头数据、Pop掉队头数据的方式来实现的。

#include "Queue.h"

void QueueTest()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);

	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);

	QueuePush(&q, 4);
	QueuePush(&q, 5);
	QueuePush(&q, 6);

	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");

	QueueDestroy(&q);
}

int main()
{
	QueueTest();

	return 0;
}

【数据结构与算法】队列的实现

👉总结👈

本篇博客主要讲解了队列的实现,最重要的函数接口是数据入队和数据出队。在下一篇博客,本人将给大家带来几道 OJ 题,大家可以期待一下。以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家啦!💖💝❣️文章来源地址https://www.toymoban.com/news/detail-471469.html

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

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

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

相关文章

  • 数据结构与算法之Python实现——队列

    在上一期博客中我们学习了栈这种结构,本期博客将学习一下跟栈很类似的一种结构——队列。 本期知识点: 顺序队列 循环队列 链式队列 队列的应用 ⚪️ 什么是队列? 队列是一种跟栈很相似的结构。我们知道栈是一种 先进后出 的结构,那么队列就像一个排队的队伍一样

    2024年02月06日
    浏览(31)
  • 【数据结构和算法】---栈和队列的互相实现

    具体题目可以参考 LeetCode 232. 用栈实现队列 首先要想到的是,队列是一种 先进先出 的结构,而栈是一种 先进后出 的结构。依此 我们可以定义两个栈结构来模拟先进先出 ,既然要定义两个栈,那么为了方便调用,我们可以将这两个栈结构定义在一个结构体中,如下: 实现

    2024年02月03日
    浏览(27)
  • 【算法与数据结构】232、LeetCode用栈实现队列

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :这道题要求我们用栈模拟队列(工作上一定没人这么搞)。程序当中,push函数很好解决,直接将元素push进输入栈当中。pop函数需要实现队列先进先出的操作,而栈是先进后出。只

    2024年02月12日
    浏览(30)
  • 【算法与数据结构】 C语言实现单链表队列详解

    前面我们学习了队列的顺序表的实现,本节将用单链表实现队列。 队列也可以数组和链表的结构实现, 使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低 。下面我们先复习一下队列的基本概念: 队列:只允许在一端进行插入

    2024年04月11日
    浏览(37)
  • 头歌(C语言)-数据结构与算法-队列-第1关:实现一个顺序存储的队列

    任务描述 相关知识 顺序存储的队列 顺序队列的主要操作 编程要求 测试说明 任务描述 本关任务:实现 step1/SeqQueue.cpp 中的 SQ_IsEmpty 、 SQ_IsFull 、 SQ_Length 、 SQ_In 和 SQ_Out 五个操作函数,以实现判断队列是否为空、是否为满、求队列长度、队列元素入队和出队等功能。 相关知

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

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

    2024年02月08日
    浏览(32)
  • C++数据结构与算法详解:链表、栈、队列、树、二叉树和图结构的实现与应用

    链表是一种常见的数据结构由一系列节点按顺序连接而成,一般每个节点包含一个数据元素和一个指向下一个节点的引用。 链表有多种类型: 单向链表:每个节点只有一个指向下一个节点的引用 双向链表:每个节点有一个指向前一个节点和一个指向后一个节点的引用 循环链

    2024年02月04日
    浏览(31)
  • 【算法数据结构专题】「延时队列算法」史上手把手教你针对层级时间轮(TimingWheel)实现延时队列的开发实战落地(下)

    承接上一篇文章【算法数据结构专题】「延时队列算法」史上手把手教你针对层级时间轮(TimingWheel)实现延时队列的开发实战落地(上)】我们基本上对层级时间轮算法的基本原理有了一定的认识,本章节就从落地的角度进行分析和介绍如何通过Java进行实现一个属于我们自

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

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

    2023年04月16日
    浏览(38)
  • 【数据结构和算法】--队列的特殊结构-循环队列

    循环队列是队列的一种特殊结构,它的 长度是固定的 k ,同样是 先进先出 ,理论结构是 首尾相连的环形循环结构 。其理论结构大致如下: 具体结构描述可以参考 LeetCode : 622. 设计循环队列的题目要求,大致如下: 设计你的循环队列实现。 循环队列是一种 线性数据结构 ,

    2024年02月04日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包