C语言队列和应用详情

C 语言队列和应用详情

什么是队列

队列是一种数据结构,可以用来存储一组按顺序排列的元素。队列的特点就是先进先出,即First In First Out,缩写为 FIFO。也就是说,最先插入队列的元素会最先被取出,最后插入队列的元素则会最后被取出。常见的生活中队列应用包括的排队取号,排队坐火车,排队打饭等等。

C 语言实现队列

在 C 语言中,我们可以通过数组来实现队列。首先定义队列结构体,包含队列的属性以及队列的值:

#define QUEUE_SIZE 100
typedef struct{
    int data[QUEUE_SIZE];   // 存放队列元素的数组
    int head;    // 队头指针
    int tail;    // 队尾指针
}Queue;

其中,data 数组是存储队列元素的数组,head 是队头指针,tail 是队尾指针。队列的初始化,队尾、队头的添加和删除操作等函数的实现如下:

// 初始化队列
void InitQueue(Queue *Q)
{
    Q->head = 0;
    Q->tail = 0;
}

// 判断队列是否为空
int QueueEmpty(Queue Q)
{
    return Q.head == Q.tail;
}

// 判断队列是否已满
int QueueFull(Queue Q)
{
    return (Q.tail + 1) % QUEUE_SIZE == Q.head;
}

// 从队尾插入元素
int EnQueue(Queue *Q, int x)
{
    if (QueueFull(*Q))    // 队列已满,插入失败
        return 0;
    Q->data[Q->tail] = x;
    Q->tail = (Q->tail + 1) % QUEUE_SIZE;
    return 1;
}

// 从队头删除元素
int DeQueue(Queue *Q, int *x)
{
    if (QueueEmpty(*Q))    // 队列为空,删除失败
        return 0;
    *x = Q->data[Q->head];
    Q->head = (Q->head + 1) % QUEUE_SIZE;
    return 1;
}

队列的应用

单词倒序

我们可以用队列来实现对单词倒序的功能。对于一段文本,我们可以将其按照空格和其他标点符号进行分割,然后将每个单词插入到队列中。最后从队列中取出单词并拼接起来就能得到倒序后的文本。

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

#define WORD_SIZE 50   // 定义单词的最大长度
#define QUEUE_SIZE 100   // 定义队列的大小

typedef struct{
    char data[WORD_SIZE];
    int length;   // 单词的实际长度
}Word;

typedef struct{
    Word data[QUEUE_SIZE];
    int head;
    int tail;
}Queue;

// 初始化队列
void InitQueue(Queue *Q)
{
    Q->head = 0;
    Q->tail = 0;
}

// 判断队列是否为空
int QueueEmpty(Queue Q)
{
    return Q.head == Q.tail;
}

// 判断队列是否已满
int QueueFull(Queue Q)
{
    return (Q.tail + 1) % QUEUE_SIZE == Q.head;
}

// 从队尾插入元素
int EnQueue(Queue *Q, char *x)
{
    if (QueueFull(*Q))    // 队列已满,插入失败
        return 0;
    Word new_word;
    new_word.length = strlen(x);
    strcpy(new_word.data, x);
    Q->data[Q->tail] = new_word;
    Q->tail = (Q->tail + 1) % QUEUE_SIZE;
    return 1;
}

// 从队头删除元素
int DeQueue(Queue *Q, Word *x)
{
    if (QueueEmpty(*Q))    // 队列为空,删除失败
        return 0;
    *x = Q->data[Q->head];
    Q->head = (Q->head + 1) % QUEUE_SIZE;
    return 1;
}

int main()
{
    char str[] = "hello, how are you today?";
    char *tok = strtok(str, " ,?!");
    Queue Q;
    InitQueue(&Q);
    while (tok != NULL)
    {
        EnQueue(&Q, tok);
        tok = strtok(NULL, " ,?!");
    }
    while (!QueueEmpty(Q))
    {
        Word w;
        DeQueue(&Q, &w);
        for (int i = w.length - 1; i >= 0; i--)
            printf("%c", w.data[i]);
        printf(" ");
    }
    printf("\n");
    return 0;
}

模拟进程调度

我们可以用队列来实现模拟进程调度。进程调度是指操作系统为了合理利用 CPU 资源,动态地将进程从就绪态调度到运行态,从而实现进程并发执行的过程。你可以将每个进程看成队列的元素,优先级高的进程先插入队列,调度的过程就是从队头取出将要执行的进程。

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

#define QUEUE_SIZE 100

typedef struct{
    int id;
    int priority;   // 进程优先级
    int remain_time;   // 剩余运行时间
}Process;

typedef struct{
    Process data[QUEUE_SIZE];   // 存放进程的数组
    int head;   // 队头指针
    int tail;   // 队尾指针
}Queue;

// 初始化队列
void InitQueue(Queue *Q)
{
    Q->head = 0;
    Q->tail = 0;
}

// 判断队列是否为空
int QueueEmpty(Queue Q)
{
    return Q.head == Q.tail;
}

// 判断队列是否已满
int QueueFull(Queue Q)
{
    return (Q.tail + 1) % QUEUE_SIZE == Q.head;
}

// 从队尾插入元素
int EnQueue(Queue *Q, Process p)
{
    if (QueueFull(*Q))    // 队列已满,插入失败
        return 0;
    Q->data[Q->tail] = p;
    Q->tail = (Q->tail + 1) % QUEUE_SIZE;
    return 1;
}

// 从队头删除元素
int DeQueue(Queue *Q, Process *p)
{
    if (QueueEmpty(*Q))    // 队列为空,删除失败
        return 0;
    *p = Q->data[Q->head];
    Q->head = (Q->head + 1) % QUEUE_SIZE;
    return 1;
}

int main()
{
    int n = 5;   // 进程数量
    Process P[n];   // 进程数组
    Queue Q;
    InitQueue(&Q);
    // 进程的初始化
    for (int i = 0; i < n; i++)
    {
        P[i].id = i;
        P[i].priority = rand() % 10;
        P[i].remain_time = rand() % 10 + 1;
        EnQueue(&Q, P[i]);
    }
    // 进行进程调度
    int time = 0;   // 系统运行的时间
    while (!QueueEmpty(Q))
    {
        printf("time = %d\n", time);
        Process p;
        DeQueue(&Q, &p);
        p.remain_time--;
        if (p.remain_time > 0)
        {
            EnQueue(&Q, p);
            printf("process%d is running (priority=%d, remain_time=%d)\n", p.id, p.priority, p.remain_time);
        }
        else
        {
            printf("process%d finished\n", p.id);
        }
        time++;
    }
    return 0;
}

以上就是 C 语言队列和应用的完整攻略,希望能帮助到大家。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言队列和应用详情 - Python技术站

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

相关文章

  • Javascript实用方法之json合并的场景分析

    Javascript实用方法之json合并的场景分析 在开发中,JSON合并是一项非常常见的需求。本篇攻略将介绍典型的JSON合并场景及其解决方案。 场景分析 假设有两个JSON对象,分别为: let object1 = { name: ‘John’, age: 25, location: { city: ‘New York’, country: ‘USA’…

    C 2023年5月23日
    00
  • Node.js处理I/O数据之使用Buffer模块缓冲数据

    Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它能够在服务器端解析 JavaScript代码,同时具有高效的I/O操作能力。其中,Buffer模块是Node.js核心库中处理二进制数据的工具之一。我们可以使用Buffer模块来创建缓冲区,对数据进行读写操作。 创建Buffer 我们可以使用以下方法来创建Buffer实例: co…

    C 2023年5月23日
    00
  • C++实现AVL树的完整代码

    实现AVL树的完整代码需要遵循以下步骤: 第一步:头文件声明 在代码文件的开头,我们需要声明头文件,以引入所需的库和类。在实现AVL树的完整代码中,我们需要添加以下头文件: #include <iostream> #include <algorithm> 这里用到了C++标准库中的iostream库,用于输入输出操作,以及algori…

    C 2023年5月24日
    00
  • C++中的friend函数详细解析

    C++中的friend函数详细解析 friend是C++语言中的一个关键字,用于在一个类中声明其它类或者函数成为友元,可以让友元类或者友元函数能够访问本类的私有成员。friend也是一个强大的功能,但是使用不当可能打破了类的封装性。 基本语法 在C++中,使用friend关键字声明一个友元类或者友元函数,例如: class MyClass{ private:…

    C 2023年5月22日
    00
  • win10系统出现0xc0000428错误的解决办法

    Win10系统出现0xc0000428错误的解决办法 问题描述 在使用Windows10系统时,有时会出现0xc0000428错误提示。该错误提示表示Windows无法验证计算机硬件或者启动配置文件,导致启动失败。这个问题可能会导致系统无法正常启动,对我们的工作和学习带来影响。因此,本文将详细介绍Win10系统出现0xc0000428错误的解决办法。 解决办…

    C 2023年5月24日
    00
  • 如何解决UnsupportedOperationException异常问题

    针对UnsupportedOperationException异常问题,可以按照以下步骤来解决: 步骤一:确定异常类型 首先找到程序出现问题的那行代码,查看控制台输出的异常信息,看看异常类型是什么,比如说是UnsupportedOperationException。 Exception in thread "main" java.lang…

    C 2023年5月23日
    00
  • 手机版CCleaner怎么卸载软件应用程序

    下面是详细讲解“手机版CCleaner怎么卸载软件应用程序”的完整攻略: CCleaner简介 CCleaner是一款著名的系统清理与优化软件,其拥有较高的用户口碑。除去PC版本之外,CCleaner还在移动端推出了相应清理软件,广受用户好评。CCleaner安装在手机上后,它可以帮助用户管理手机存储空间,清理垃圾数据,优化手机性能。但有时,当用户不再需要某…

    C 2023年5月23日
    00
  • 在1个Matlab m文件中定义多个函数直接运行的操作方法

    在一个 Matlab 的 m 文件中定义多个函数可以大大提高代码的可读性和复用性,以下是操作方法的具体攻略: 在一个 Matlab 的 m 文件中定义多个函数,需要注意每个函数的开头应有相应的函数名和输入/输出参数的定义。例如: function y = func1(x) % This is function 1 y = x + 1; end functio…

    C 2023年5月30日
    00
合作推广
合作推广
分享本页
返回顶部