<队列>的概念&结构&实现【C语言版】

简介: <队列>的概念&结构&实现【C语言版】

0.png

正文


1.队列的概念及结构


队列对于临时数据的处理也十分有趣,它跟栈一样都是有约束条件的数组(或者链表)。区别在于我们想要按什么顺序去处理数据,而这个顺序当然是要取决于具体的应用场景。


你可以将队列想象成是电影院排队。排在最前面的人会最先离队进入影院。套用到队列上,就是首先加入队列的,将会首先从队列移出。


因此计算机科学家都用缩写“FIFO”(first in, first out)先进先出,来形容它。


与栈类似,队列也有 3个限制(但内容不同)。


 ▶ 只能在末尾插入数据(这跟栈一样)。

 ▶ 只能读取开头的数据(这跟栈相反)。

 ▶ 只能移除开头的数据(这也跟栈相反)。


下面来看看它是怎么运作的,先准备一个空队列。


首先,插入 5(虽然栈的插入就叫压栈,但队列的插入却没有固定的叫法,一般可以叫放入、加入、入队)。

43.png

然后,插入 9。

44.png

接着,插入 100。


45.png


目前为止,队列表现得还跟栈一样,但要是移除数据的话,就会跟栈反着来了,因为队列是从开头移除数据的。


想移除数据,得先从 5 开始,因为开头就是它。

34.png

接着,移除 9。

33.png

这样一来,队列就只剩下 100了。


2.队列的实现


队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。


2.1队列结构的定义


typedef struct Queue
{
  QNode* head; //记录队头的位置
  QNode* tail; //记录队尾的位置
  int size; //记录队列的长度
}Queue;


2.2队列中存储数据的结点


typedef int QDataType;
typedef struct QueueNode
{
  QDataType data; //存储的数据
  struct QueueNode* next; //记录下一个结点的位置
}QNode;


2.3函数接口的实现


首先是在Queue.h文件中进行函数声明


Queu.h


#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.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);
//释放malloc出的内存
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文件中进行函数的定义


Queue.c


#define _CRT_SECURE_NO_DEPRECATE 1
#include"Queue.h"
void QueueInit(Queue* pq)
{
  assert(pq);
  pq->head = NULL;
  pq->tail = NULL;
  pq->size = 0;
}
void QueueDestroy(Queue* pq)
{
  assert(pq);
  //用cur找尾
  QNode* cur = pq->head;
  while (cur)
  {
    QNode* del = cur;
    cur = cur->next;
    free(del);
  }
  pq->size = 0;
  pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq,QDataType data)
{
  assert(pq);
  QNode* newNode = (QNode*)malloc(sizeof(QNode));
  if (newNode == NULL)
  {
    perror("malloc fail");
    exit(-1);
  }
  //初始化结点
  newNode->data = data;
  newNode->next = NULL;
  if (pq->tail == NULL)
  {
    //队列为空时入队
    pq->head = newNode;
    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);
  }
  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;
}


目录
相关文章
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
236 9
|
3月前
|
网络协议 编译器 Linux
【C语言】结构体内存对齐:热门面试话题
【C语言】结构体内存对齐:热门面试话题
111 0
|
2月前
|
C语言 开发者
C语言中的模块化编程思想,介绍了模块化编程的概念、实现方式及其优势,强调了合理划分模块、明确接口、保持独立性和内聚性的实践技巧
本文深入探讨了C语言中的模块化编程思想,介绍了模块化编程的概念、实现方式及其优势,强调了合理划分模块、明确接口、保持独立性和内聚性的实践技巧,并通过案例分析展示了其应用,展望了未来的发展趋势,旨在帮助读者提升程序质量和开发效率。
64 5
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
68 5
|
2月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
104 16
|
3月前
|
编译器 C语言 Python
C语言结构
C语言结构
22 0
|
4月前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
4月前
|
存储 机器学习/深度学习 C语言
数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
|
1月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
62 10