数据结构:线性表(队列实现)

news2024/11/18 7:29:14

1. 队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除操作的特殊线性表,队列具有先进先出(FIFO)的特性.
进行插入操作的一端称为队尾;进行删除操作的一端叫做队头

在这里插入图片描述

队列应用于

  1. 解决公平性排队(抽号机)
  2. 广度优先遍历(BFS)

2. 队列的定义

和栈一样,队列也可以使用两种物理结构进行存储:数组存储和链表存储
但是更推荐使用链表进行实现,链表尾插头删,相比于数组尾插头删所消耗的时间要小很多

注: 如果实现循环队列,更推荐使用数组

  • 单链表实现队列的头删尾插图示:
    在这里插入图片描述
    在这里插入图片描述

  • 队列的链式实现

typedef int QDataType;

// 链式结构表示队列
typedef struct QListNode
{
  struct QListNode* next;
  QDataType data;
}QNode;

// 队列的结构
typedef struct Queue
{
  QNode* front;    //指向队列头
  QNode* rear;     //指向队列尾
  int size;        //记录队列的元素个数
}Queue;
  1. 队列的每个结点使用链表结点
  2. 同时,在单链表的基础上,队列还多加了两个指针指向头尾,方便使用 O ( 1 ) O(1) O(1)的时间复杂度找到队列的头和尾,进行头删尾插
  • 队列相关接口函数
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType x);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列尾部元素
QDataType QueueBack(Queue* q);
// 获取队列有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空, 如果为空返回非零结果, 如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);

3. 队列的实现

3.1 初始化队列 (QueueInit)

// 初始化队列
void QueueInit(Queue* q)
{
  assert(q);  //确保q合法

  q->front = q->rear = NULL;  //将头和为置为 NULL 
  q->size = 0;
}
  1. 首先确保 q 合法
  2. 将队列中的成员变量初始化, 头尾指针置为 NULL, 队列的大小置为 0

3.2 队尾入队列 (QueuePush)

void QueuePush(Queue* q, QDataType x)
{
  assert(q);  //确保q合法

  //创建新结点
  QNode* newNode = (QNode*)malloc(sizeof(QNode));
  newNode->data = x;
  newNode->next = NULL;

  //入队列
  if (QueueEmpty(q))
  {
    //如果队列为空,直接赋值
    q->front = q->rear = newNode;
  }
  else 
  {
    //如果队列不为空,直接尾插
    q->rear->next = newNode;
    q->rear = newNode;
  }

  q->size++;
}

  1. 首先确保 q 合法
  2. 创建新结点
  3. 进行队列的尾插,分为两种情况:队列为空的时候直接赋值;队列不为空的时候正常进行尾插

3.2 队头出队列 (QueuePop)

void QueuePop(Queue* q)
{
  assert(q);  //确保q合法
  assert(!QueueEmpty(q)); //确保队列不为空

  if (q->size == 1)
  {
    //如果只有一个元素,头删的同时还要将尾指针置空
    free(q->front);
    q->front = q->rear = NULL;
  }
  else 
  {
    //如果不止一个元素,则只头删
    QNode* nextNode = q->front->next;
    free(q->front);
    q->front = nextNode;
  }

  q->size--;
}
  1. 首先确保 q 合法
  2. 分为三种情况:
    • 队列为空直接返回错误
    • 队列只有一个结点,头尾指针都置空
    • 队列有两个及以上的结点,简单头删

3.3 获取队列头部元素 (QueueTop)

QDataType QueueFront(Queue* q)
{
  assert(q);  //确保q合法
  assert(!QueueEmpty(q)); //确保队列不为空

  return q->front->data;
}

3.4 获取队列尾部元素 (QueueBack)

QDataType QueueBack(Queue* q)
{
  assert(q);  //确保q合法
  assert(!QueueEmpty(q)); //确保队列不为空

  return q->rear->data;
}

3.5 获取队列大小 (QueueSize)

int QueueSize(Queue* q)
{
  assert(q);  //确保q合法

  return q->size;
} 

3.6 判断队列是否为空, 如果为空返回非0, 非空返回0 (QueueEmpyt)

int QueueEmpty(Queue* q)
{
  assert(q);  //确保q合法

  if (q->size == 0)
  {
    return 1;
  }
  else 
  {
    return 0;
  }
}

3.7 销毁队列 (QueueDestroy)

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

  while(!QueueEmpty(q))
  {
    QNode* nextNode = q->front->next;
    free(q->front);
    q->front = nextNode;
  }

  q->front = q->rear = NULL;
  q->size = 0;
}
  1. 首先确保 q 合法
  2. 从头遍历队列,依次释放每个结点的空间,注意先要记录当前要销毁结点的下一个结点.

3.8 完整代码

  • Queue.h
#pragma once 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int QDataType;

// 链式结构表示队列
typedef struct QListNode
{
  struct QListNode* next;
  QDataType data;
}QNode;

// 队列的结构
typedef struct Queue
{
  QNode* front;    //指向队列头
  QNode* rear;     //指向队列尾
  int size;        //记录队列的元素个数
}Queue;

// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType x);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列尾部元素
QDataType QueueBack(Queue* q);
// 获取队列有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空, 如果为空返回非零结果, 如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);

  • Queue.c
#pragma once 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int QDataType;

// 链式结构表示队列
typedef struct QListNode
{
  struct QListNode* next;
  QDataType data;
}QNode;

// 队列的结构
typedef struct Queue
{
  QNode* front;    //指向队列头
  QNode* rear;     //指向队列尾
  int size;        //记录队列的元素个数
}Queue;

// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType x);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列尾部元素
QDataType QueueBack(Queue* q);
// 获取队列有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空, 如果为空返回非零结果, 如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);

  • test.c
#include "Queue.h"

void QueueTest1()
{
  Queue queue;
  QueueInit(&queue);
  QueuePush(&queue, 1);
  QueuePush(&queue, 2);
  QueuePush(&queue, 3);
  QueuePush(&queue, 4);
  QueuePush(&queue, 5);
  QueuePop(&queue);
  QueuePop(&queue);
  QueuePop(&queue);
  QueuePop(&queue);
  QueuePop(&queue);
  QueuePop(&queue);
}

void QueueTest2()
{
  Queue queue;
  QueueInit(&queue);
  QueuePush(&queue, 1);
  QueuePush(&queue, 2);
  QueuePush(&queue, 3);
  QueuePush(&queue, 4);
  QueuePush(&queue, 5);
  QueuePush(&queue, 6);

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

}
int main(void)
{
  //QueueTest1();
  QueueTest2();

  return 0;
}

本章完.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1001671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【知网检索】第三届教育,语言与艺术国际学术会议(ICELA 2023)

第三届教育&#xff0c;语言与艺术国际学术会议(ICELA 2023) The 3rd International Conference on Education, Language and Art 第三届教育&#xff0c;语言与艺术国际学术会议&#xff08;ICELA 2023&#xff09;将于2023年11月17-19日在中国北京召开。会议主要围绕会议主…

电力系统知识预备及学习方向

由于电源点与负荷中心多数处于不同地区&#xff0c;也无法大量储存&#xff0c;故其生产、输送、分配和消费都在同一时间内完成&#xff0c;并在同一地域内有机地组成一个整体&#xff0c;电能生产必须时刻保持与消费平衡。因此&#xff0c;电能的集中开发与分散使用&#xff0…

explainerdashboard,一个神奇的 python 库

今天给大家分享一个神奇的 python 库&#xff0c;explainerdashboard。 https://github.com/oegedijk/explainerdashboard explainerdashboard 是一种用户友好的工具&#xff0c;可以简化复杂的机器学习模型&#xff0c;解释&#xff08;与 scikit-learn 兼容&#xff09;机器…

Bodhi Linux 7.0发布:全新亮点抢先看

导读我们非常高兴地宣布Bodhi Linux 7.0的发布&#xff0c;这是一个小型开发团队经过数月的专注开发所取得的成果。从性能增强到尖端更新&#xff0c;让我们深入了解这个版本&#xff0c;看看它为那些寻求轻量级Linux桌面体验的用户带来了什么新特性。 Bodhi Linux 7.0桌面 Bo…

12.(Python数模)(相关性分析一)相关系数矩阵

相关系数矩阵 相关系数矩阵是用于衡量多个变量之间关系强度和方向的统计工具。它是一个对称矩阵&#xff0c;其中每个元素表示对应变量之间的相关系数。 要计算相关系数矩阵&#xff0c;首先需要计算每对变量之间的相关系数。常用的相关系数包括皮尔逊相关系数和斯皮尔曼相关…

第32章 Linux内核打印实验

本手册的实验都是在buildroot系统上完成的&#xff0c;由于buildroot系统已经设置了相应的打印等级&#xff0c;所以驱动的相关打印都能正常显示在串口终端上&#xff0c;如果将实验系统换成了ubuntu&#xff0c;然后加载同样的驱动&#xff0c;会发现打印信息不见了&#xff0…

PBR纹理的10种贴图

PBR 是基于物理的渲染的首字母缩写。它试图通过模拟材料如何吸收和反射光&#xff0c;以模仿现实世界中的光流的方式产生视觉效果。最近的游戏引擎由于其逼真的效果而越来越多地使用 PBR 纹理。对于实时渲染&#xff0c;它们被认为是真实世界场景的最佳近似值。 推荐&#xff…

极星 4:一辆不需要宣传就自带美学的车

当市面上的新车都开始逐步走向更多的功能、更繁琐的设计的时候&#xff0c;极星更像一个独行的人&#xff0c;走了一条跟其他车企大相径庭的道路&#xff0c;带给我们对于同一个世界不同的视图。 不张扬、够简洁&#xff0c;从不炫耀自己但又蕴含着大的智慧&#xff0c;如夜空中…

Python深度学习-Keras》精华笔记4:解决深度学习回归问题

公众号&#xff1a;尤而小屋作者&#xff1a;Peter编辑&#xff1a;Peter 持续更新《Python深度学习》一书的精华内容&#xff0c;仅作为学习笔记分享。 本文是第4篇&#xff1a;基于Keras解决深度学习中的回归问题。 Keras内置数据集 回归问题中使用的是内置的波士顿房价数据…

JavaScript中的事件捕获(event capturing)和事件冒泡(event bubbling)

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 事件捕获和事件冒泡⭐ 事件捕获&#xff08;Event Capturing&#xff09;示例&#xff1a; ⭐ 事件冒泡&#xff08;Event Bubbling&#xff09;示例&#xff1a; ⭐ 应用场景⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开…

苹果电脑版虚拟机推荐 VMware Fusion Pro for mac(vm虚拟机)

VMware Fusion Pro是一款功能强大的虚拟化软件&#xff0c;专为Mac用户设计。它允许用户在Mac上创建、运行和管理虚拟机&#xff0c;以便同时运行多个操作系统和应用程序。 以下是VMware Fusion Pro的一些主要特点和功能&#xff1a; 1. 多操作系统支持&#xff1a;VMware Fu…

CocosCreator3.6.2图片导入到工程,没办法拖动到场景中

解决方案&#xff1a;将资源的属性类型由texture调整为sprite-frame

字节、华为、美团软件测试面试真题(超详细~)

前言 最近已经算是秋招了&#xff0c;所以最近博主会努力给大家搜集整理一些各大公司测试岗测开岗的面经&#xff0c;希望能帮助到大家更好的入职想去的公司哦&#xff0c;关注我&#xff0c;一个每日分享软件测试知识的日更博主。 同时&#xff0c;我也准备了一份软件测试面…

Git 概述命令、idea中的使用

目录 Git概述 Git代码托管服务 Git常用命令 Git 全局设置 获取 Git 仓库 ​编辑Git 工作区中文件的状态 本地仓库操作 远程仓库操作 ​编辑分支操作 标签操作 在IDEA中使用Git 1.获取Git仓库 .gitignore 表示忽略 2.本地仓库操作 3.远程仓库操作 4.分支操作 Git是…

C++项目实战——基于多设计模式下的同步异步日志系统-⑤-实用工具类设计与实现

文章目录 专栏导读获取系统时间time介绍 getTime函数设计判断文件是否存在stat介绍exists函数设计 获取文件所在路径find_last_of介绍path函数设计 创建文件所在目录mkdir介绍find_first_of介绍函数createDirectory设计 实用工具类整理 专栏导读 &#x1f338;作者简介&#xf…

智慧公厕助力数字强市建设,打造善感知新型信息化公共厕所

随着城市建设的不断发展&#xff0c;智慧公厕作为一个重要的基础设施&#xff0c;正逐渐受到人们的重视。智慧公厕不仅为人们提供舒适的使用环境&#xff0c;更是通过数字化技术的应用&#xff0c;为城市发展注入新的动力。本文将以智慧公厕源头厂家广州中期科技有限公司&#…

我是如何用 redis 分布式锁来解决线上历史业务问题的

近期发现&#xff0c;开发功能的时候发现了一个 mq 消费顺序错乱&#xff08;历史遗留问题&#xff09;&#xff0c;导致业务异常的问题&#xff0c;看看我是如何解决的 问题抛出 首先&#xff0c;简单介绍一下情况&#xff1a; 线上 k8s 有多个 pod 会去消费 mq 中的消息&a…

编写更嵌入式软件代码的10个技巧

代码维护是应用程序开发的重要方面&#xff0c;而为了缩短上市时间&#xff0c;通常会忽略代码维护。对于某些应用程序&#xff0c;这可能不会造成重大问题&#xff0c;因为这些应用程序的寿命很短&#xff0c;或者已部署该应用程序&#xff0c;并且再也不会碰它。 但是&#x…

UIScrollView setContentOffset: animated:

项目中遇到感觉一切都设置对了&#xff0c;但是看到的效果和预想的不一样。 后来查询了一番&#xff0c;才知道问题所在&#xff0c;现在记录一下&#xff0c;担心过后又忘了。 最初的问题是这样的&#xff0c;这个热度只有在评论里有&#xff0c;点击赞的时候&#xff0c;热度…