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

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日

相关文章

  • 【ACM博弈论】SG函数入门(2):博弈树SG函数的转移与子游戏的合并

    上一篇文章我们讲了两种经典的博弈模型:《【ACM博弈论】SG函数入门(1):从巴什博奕到尼姆游戏》,这一节我们开始讲解SG函数。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 阅读原文获得更好阅读体验:https:…

    算法与数据结构 2023年4月17日
    00
  • 四边形不等式学习笔记

    简要题意 四边形不等式是一种 dp 优化策略。多用于 2D DP。 内容 对于区间 \([l,r]\) 带来的贡献 \(w(l,r)\),如果其满足: 对于 \(L\leq l\leq r \leq R\),\(w(L,r)+w(l,R)\leq w(L,R)+w(l,r)\) 则称 \(w\) 满足四边形不等式。特别地,如果上式符号取等,则称其满足四边形恒…

    算法与数据结构 2023年4月17日
    00
  • C++数据结构之链表详解

    C++数据结构之链表详解 链表是一种重要的数据结构,它可以动态的分配内存空间,实现灵活的元素插入,删除等操作。本文将详细讲解链表的定义、实现、常见操作以及链表的应用。 定义与特点 链表是一种线性表数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表分为单向链表和双向链表,其中单向链表的每个节点只包含一个指针,指向下一个节点,而双向链表的每…

    数据结构 2023年5月17日
    00
  • 数据结构 红黑树的详解

    数据结构:红黑树的详解攻略 一、红黑树的定义 红黑树是一种二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是红色或黑色。红黑树的特征是对于任何有效的红黑树,从根到叶子结点或空子结点的每条路径都包含相同数目的黑色结点。 二、插入操作 对于新插入的节点,将其涂红并插入红黑树中,然后按照二叉搜索树的规则将其插入到红黑树中。 如果父节点是黑色,则不需…

    数据结构 2023年5月17日
    00
  • Java深入了解数据结构之优先级队列(堆)

    Java深入了解数据结构之优先级队列(堆) 本文将会详细介绍Java中的优先级队列,即堆数据结构的实现过程和使用方法。 什么是优先级队列? 在介绍优先级队列之前,我们需要了解先进先出队列(FIFO Queue)和后进先出队列(LIFO Queue,或称栈)的概念。FIFO Queue按照元素的插入顺序依次出队;而LIFO Queue则按照元素的插入顺序反向出…

    数据结构 2023年5月17日
    00
  • 字典树的基本知识及使用C语言的相关实现

    字典树的基本知识 字典树,英文名为Trie树,又称单词查找树或键树,是一种树形数据结构,用于表示关联数组或映射。它的优点是,可以大大减少无谓的字符串比较,查询效率比哈希表高。 字典树的核心概念是节点,每个节点包含一个字符和指向子节点的指针。根节点为空字符,每个字符串以一个独立的路径插入节点。如果一个字符串是另一个字符串的前缀,那么这个字符串的节点是另一个字符…

    数据结构 2023年5月17日
    00
  • JavaScript的Set数据结构详解

    JavaScript中的Set数据结构详解 什么是Set? Set 是一种 Javascript 内置的数据结构。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,可以通过new关键字来创建 Set 数据结构。 let mySet = new Set(); Set的基本用法 Set实例对象有以下常用方法: add(value):…

    数据结构 2023年5月17日
    00
  • 【ACM组合数学 | 错排公式】写信

    题目链接:https://ac.nowcoder.com/acm/contest/54484/B 题意很简单,但是数据范围偏大。 错排公式 首先来推导一下错排公式: \[D(n) = n!\sum_{k=0}^{n}\frac{(-1)^k}{k!} \] 设一个函数: \[S_i表示一个排列中p_i = i的方案数 \] 那么我们可以知道: \[D(n) …

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