C语言数据结构之队列的定义与实现

yizhihongxing

C语言数据结构之队列的定义与实现

什么是队列

队列是一种特殊的线性数据结构,它只允许在队列的头部进行删除操作,在队列的尾部进行插入操作,这种操作方式被成为“先进先出”或“FIFO(first in first out)”。

队列的实现方式

队列可以通过数组和链表两种方式进行实现。

1. 数组实现

数组实现队列时,可以定义一个存放元素的数组,同时需要记录队列的头部和尾部。队列头的位置表示下一次从队列中取出元素的位置,而队列尾的位置表示下一次插入元素的位置,代码实现如下:

#define MAX_QUEUE_SIZE 100     // 定义队列最大长度
typedef struct {
    int queue[MAX_QUEUE_SIZE];  // 存放元素的数组
    int front;                  // 队列头部位置
    int rear;                   // 队列尾部位置
} ArrayQueue;

// 初始化队列
void initQueue(ArrayQueue* queue) {
    queue->front = queue->rear = 0;
}

// 入队列
void enqueue(ArrayQueue* queue, int element) {
    if ((queue->rear + 1) % MAX_QUEUE_SIZE == queue->front) {
        printf("队列已满,无法插入元素");
        return;
    }
    queue->queue[queue->rear] = element;
    queue->rear = (queue->rear + 1) % MAX_QUEUE_SIZE;
}

// 出队列
int dequeue(ArrayQueue* queue) {
    if (queue->front == queue->rear) {
        printf("队列为空,无法取出元素");
        return -1;
    }
    int element = queue->queue[queue->front];
    queue->front = (queue->front + 1) % MAX_QUEUE_SIZE;
    return element;
}

上述代码中,队列的最大长度是100,当队列满时需要进行数据搬移,代码中通过取模操作实现了循环队列的功能。

2. 链表实现

链表实现队列时,可以定义一个单链表,用链表的头结点表示队列的头部,而链表的尾结点表示队列的尾部,代码实现如下:

typedef struct LinkedNode {
    int data;                      // 链表节点存放的元素
    struct LinkedNode* next;       // 指向下一个节点的指针
} LinkedNode;

typedef struct {
    LinkedNode* front;        // 队列头部
    LinkedNode* rear;         // 队列尾部
} LinkQueue;

// 初始化队列
void initQueue(LinkQueue* queue) {
    queue->front = queue->rear = NULL;
}

// 入队列
void enqueue(LinkQueue* queue, int element) {
    LinkedNode* node = (LinkedNode*)malloc(sizeof(LinkedNode));
    node->data = element;
    node->next = NULL;
    if (queue->rear == NULL) {
        queue->front = queue->rear = node;
    } else {
        queue->rear->next = node;
        queue->rear = node;
    }
}

// 出队列
int dequeue(LinkQueue* queue) {
    if (queue->front == NULL) {
        printf("队列为空,无法取出元素");
        return -1;
    }
    LinkedNode* node = queue->front;
    int element = node->data;
    queue->front = queue->front->next;
    if (queue->front == NULL) {
        queue->rear = NULL;
    }
    free(node);
    return element;
}

队列的应用

队列的应用场景非常广泛,例如:

1. 广度优先搜索算法

广度优先搜索算法就需要借助一个队列,将遍历的节点依次入队列,然后按照队列的顺序出队列,实现图的遍历。

void BFS(LinkedList* graph, int start) {
    Queue queue;
    int isVisited[MAX_VERTEX_NUM] = {0};
    insertQueue(&queue, start);
    isVisited[start] = 1;
    while (!isQueueEmpty(&queue)) {
        int current = deleteQueue(&queue);
        printf("%d ", current);
        LinkedListNode* node = graph->adjList[current].firstNode;
        while (node != NULL) {
            int vertex = node->vertex;
            if (!isVisited[vertex]) {
                insertQueue(&queue, vertex);
                isVisited[vertex] = 1;
            }
            node = node->next;
        }
    }
}

2. 操作系统中的进程调度

在操作系统中,进程调度通常是使用队列来实现的,将需要执行的进程按照优先级放入对应的队列中,然后按照队列的顺序依次调度执行。

// 定义进程
typedef struct {
    int pid;            // 进程ID
    int priority;       // 进程优先级
    int burst_time;     // 进程执行时间
} Process;

// 定义队列
typedef struct {
    Process* p[MAX_QUEUE_SIZE];
    int front;
    int rear;
} ProcessQueue;

// 入队列
void enqueueProcess(ProcessQueue* queue, Process* p) {
    if ((queue->rear + 1) % MAX_QUEUE_SIZE == queue->front) {
        printf("队列已满,无法插入进程");
        return;
    }
    queue->p[queue->rear] = p;
    queue->rear = (queue->rear + 1) % MAX_QUEUE_SIZE;
}

// 出队列
Process* dequeueProcess(ProcessQueue* queue) {
    if (queue->front == queue->rear) {
        printf("队列为空,无法取出进程");
        return NULL;
    }
    Process* p = queue->p[queue->front];
    queue->front = (queue->front + 1) % MAX_QUEUE_SIZE;
    return p;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构之队列的定义与实现 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • mysql的Buffer Pool存储及原理解析

    下面我就来详细讲解一下“mysql的Buffer Pool存储及原理解析”的攻略。 Buffer Pool简介 在MySQL中,Buffer Pool是一个重要的概念,也可以说是MySQL最重要的性能优化建议之一。Buffer Pool是MySQL内存中缓存数据页的数据结构,用于加速数据的读写。 数据页 在MySQL中,数据是以数据页(page)为单位进行读…

    数据结构 2023年5月17日
    00
  • 「线段树」!(简单)的线段树

    本题为3月20日23上半学期集训每日一题中B题的题解 题面 题目描述 给你一个序列 \(A[1],A[2],…,A[n]\) .( \(|A[i]| \leq 15007, 1 \leq N \leq 50,000\) ). M( \(1 \leq M \leq 500,000\) ) 次询问,每次询问 \(Query(x, y) = Max{A[i] …

    算法与数据结构 2023年4月18日
    00
  • 数据结构与算法之手撕排序算法

    数据结构与算法之手撕排序算法 本篇攻略介绍如何手撕常见的排序算法。 冒泡排序 冒泡排序是一种通过不断交换相邻元素来排序的方法。它的时间复杂度为$O(n^2)$。 def bubble_sort(nums): for i in range(len(nums)): for j in range(len(nums)-i-1): if nums[j] > nu…

    数据结构 2023年5月17日
    00
  • C++抽象数据类型介绍

    C++抽象数据类型介绍 什么是抽象数据类型? 抽象数据类型(Abstract Data Type,ADT),是数据类型的一个数学模型。它实现了数据类型的抽象过程,将数据与操作分离,使得操作具有独立性,而数据只作为函数参数和返回值存在。 举个例子,ADT可以定义一个栈(Stack),栈的实现需要以下操作: 初始化栈 压入数据 弹出数据 获取栈顶数据 检查栈是否…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构链表知识详解

    JavaScript数据结构链表知识详解 什么是链表 链表是一种线性结构,相比于数组,它不需要一块连续的内存空间,而是通过指针将一组零散的内存块串联起来使用。链表只保持一个指向链表中第一个节点的引用,每个节点则有指向下一个节点的指针。 链表的实现 链表的实现方式有很多种,下面介绍一种简单的单向链表实现方式,其中每个节点包含一个value属性和一个next属性…

    数据结构 2023年5月17日
    00
  • 算法总结–ST表

    声明(叠甲):鄙人水平有限,本文为作者的学习总结,仅供参考。 1. RMQ 介绍 在开始介绍 ST 表前,我们先了解以下它以用的场景 RMQ问题 。RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ…

    算法与数据结构 2023年4月18日
    00
  • 关于图片存储格式的整理(BMP格式介绍)

    关于图片存储格式的整理(BMP格式介绍) 一、BMP格式概述 BMP全称为Bitmap,是一种基础的图像保存格式,它的格式十分简单,就是将每个像素点的颜色信息直接保存在文件中,因此它的信息量相对较大。 BMP格式的文件头有标准结构,其中包含位图的宽、高、颜色数、位图大小等信息,其中颜色数的位数(色深)决定了BMP文件的大小。BMP文件还可以包含调色板,来进行…

    数据结构 2023年5月17日
    00
  • TypeScript数据结构链表结构 LinkedList教程及面试

    TypeScript数据结构链表结构 LinkedList教程及面试攻略 在程序设计中,链表是一种重要的数据结构,它可以用来存储一系列数据元素,并提供一些类似于数组的操作。 TypeScript是一种JavaScript的超集,它提供了更加丰富的类型系统,使得我们可以更好的使用链表这种数据结构。 本文将会讲解使用TypeScript实现常见的链表结构,并且提…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部