C语言设计前中后队列实例代码

C语言设计前中后队列实例代码攻略

在本篇文章中,我们将学习如何在C语言中设计前、中、后队列,并提供相应的示例代码。下面将分别对前、中、后队列进行介绍和说明。

前队列

前队列,也称为顺序队列。它是一种数据结构,它具有先进先出(First in First Out,简称FIFO)的特点,是一种简单但基本的数据结构,常用在队列缓存、消息队列、web服务器等领域。下面是前队列的基本操作:

初始化队列

#define MAXSIZE 50 // 定义队列的最大长度
typedef struct {
    int data[MAXSIZE]; // 存放队列元素
    int front; // 队首指针
    int rear; // 队尾指针
} SqQueue;

void initQueue(SqQueue *q) { // 初始化队列
    q->front = q->rear = 0; // 初始化队首和队尾指针
}

判断队列是否为空

int isEmpty(SqQueue q) { // 判断队列是否为空
    if (q.front == q.rear) { // 如果队首和队尾相等,即为一个空队列
        return 1; // 返回真
    } else {
        return 0; // 返回假
    }
}

入队操作

int enQueue(SqQueue *q, int e) { // 入队操作
    if ((q->rear + 1) % MAXSIZE == q->front) { // 队列已满,无法入队
        return 0;
    }
    q->data[q->rear] = e; // 将元素e插入队尾位置
    q->rear = (q->rear + 1) % MAXSIZE; // 队尾指针向后移动一位,取模运算是为了防止数组越界
    return 1;
}

出队操作

int deQueue(SqQueue *q, int *e) { // 出队操作
    if (isEmpty(*q)) { // 队列为空,无法出队
        return 0;
    }
    *e = q->data[q->front]; // 队首元素出队
    q->front = (q->front + 1) % MAXSIZE; // 队首指针向后移动一位,取模运算是为了防止数组越界
    return 1;
}

示例说明

下面是一个在前队列中入队5个元素,然后依次出队的操作:

int main() {
    int e; // 定义一个中间变量
    SqQueue q; // 定义一个队列
    initQueue(&q); // 初始化队列
    printf("队列是否为空:%d\n", isEmpty(q)); // 队列是否为空:1

    enQueue(&q, 1); // 入队操作
    enQueue(&q, 2);
    enQueue(&q, 3);
    enQueue(&q, 4);
    enQueue(&q, 5);

    printf("队列是否为空:%d\n", isEmpty(q)); // 队列是否为空:0

    while (!isEmpty(q)) { // 循环出队操作
        deQueue(&q, &e);
        printf("%d ", e);
    }

    return 0;
}

中队列

中队列的操作和前队列大部分相同,区别在于中队列在出队操作时,不是将队首元素出队,而是将队列中间位置的元素出队。由于中队列操作和前队列基本一致,这里我们不再赘述前队列中的操作。

出队操作

int deMidQueue(SqQueue *q, int *e) { // 出队操作
    if (isEmpty(*q)) { // 队列为空,无法出队
        return 0;
    }
    int mid = (q->front + q->rear - 1) / 2; // 中间位置的下标
    *e = q->data[mid]; // 中间位置元素出队
    for (int i = mid; i < q->rear - 1; i++) { // 将中间位置后面的元素依次向前移动一位
        q->data[i] = q->data[i+1];
    }
    q->rear--; // 将队尾指针向前移动一位
    return 1;
}

示例说明

下面是一个在中队列中入队5个元素,然后依次出队的操作:

int main() {
    int e; // 定义一个中间变量
    SqQueue q; // 定义一个队列
    initQueue(&q); // 初始化队列
    printf("队列是否为空:%d\n", isEmpty(q)); // 队列是否为空:1

    enQueue(&q, 1); // 入队操作
    enQueue(&q, 2);
    enQueue(&q, 3);
    enQueue(&q, 4);
    enQueue(&q, 5);

    printf("队列是否为空:%d\n", isEmpty(q)); // 队列是否为空:0

    while (!isEmpty(q)) { // 循环出队操作
        deMidQueue(&q, &e);
        printf("%d ", e);
    }

    return 0;
}

后队列

后队列,又称为链队列。在后队列链表中,队列的两端都定义在链表的两个头部,不仅需要维持队头指针,还要维护队尾指针。与前队列和中队列不同,后队列在出队操作时只是将队首元素出队,并且队列为空的判断也不同。下面是后队列的基本操作:

定义一个链表节点

typedef struct node {
    int data; // 存放元素值
    struct node *next; // 指向下一个节点
}QNode;

定义队列

typedef struct {
    QNode *front; // 队首指针
    QNode *rear; // 队尾指针
} LinkQueue;

void initQueue(LinkQueue *q) { // 初始化队列
    QNode *head = (QNode *)malloc(sizeof(QNode));
    head->next = NULL;
    q->front = q->rear = head;
}

判断队列是否为空

int isEmpty(LinkQueue q) { // 判断队列是否为空
    if (q.front == q.rear) { // 如果队首和队尾相等,即为一个空队列
        return 1; // 返回真
    } else {
        return 0; // 返回假
    }
}

入队操作

int enQueue(LinkQueue *q, int e) { // 入队操作
    QNode *p = (QNode *)malloc(sizeof(QNode)); // 创建新节点
    p->data = e; // 将元素插入节点中
    p->next = NULL; // 在链表末尾添加新节点
    q->rear->next = p; // 更新队尾指针
    q->rear = p;
    return 1;
}

出队操作

int deQueue(LinkQueue *q, int *e) { // 出队操作
    if (isEmpty(*q)) { // 队列为空,无法出队
        return 0;
    }
    QNode *p = q->front->next; // 获取队首节点
    *e = p->data; // 队首元素出队
    q->front->next = p->next; // 更新队首指针
    if (q->rear == p) q->rear = q->front; // 如果队首指针指向的是链表中的最后一个节点,则更新队尾指针
    free(p); // 释放空间
    return 1;
}

示例说明

下面是一个在后队列中入队5个元素,然后依次出队的操作:

int main() {
    int e; // 定义一个中间变量
    LinkQueue q; // 定义一个队列
    initQueue(&q); // 初始化队列
    printf("队列是否为空:%d\n", isEmpty(q)); // 队列是否为空:1

    enQueue(&q, 1); // 入队操作
    enQueue(&q, 2);
    enQueue(&q, 3);
    enQueue(&q, 4);
    enQueue(&q, 5);

    printf("队列是否为空:%d\n", isEmpty(q)); // 队列是否为空:0

    while (!isEmpty(q)) { // 循环出队操作
        deQueue(&q, &e);
        printf("%d ", e);
    }

    return 0;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言设计前中后队列实例代码 - Python技术站

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

相关文章

  • C语言基础 原码、反码、补码和移码详解

    C语言基础 原码、反码、补码和移码详解 在计算机领域,数据一般使用二进制表示,而原码、反码、补码和移码就是将数据转换为二进制表示时的一些规则和方法。 什么是原码? 原码就是一个数的二进制表示,符号位为数据的最高位,0表示正数,1表示负数。例如,-5 的原码就是: 10000101 什么是反码? 反码就是将一个数的原码取反得到的二进制表示。对于正数,其反码就是…

    C 2023年5月23日
    00
  • Vue编写多地区选择组件

    下面是关于如何使用Vue编写多地区选择组件的完整攻略: 1. 安装和引入相关组件 首先,需要安装和引入Vue框架及相关组件,让我们先来安装Vue: npm install vue 然后,我们需要安装一些用于处理地区选择的相关组件,如vue-i18n、vue-select和vue-multiselect。 分别安装方法如下: npm install vue-i…

    C 2023年5月23日
    00
  • C语言程序设计

    第一章程序设计与C语言 1,机器语言属于第一代计算机语言,能直接识别和接受的二进制代码称为机器指令,用机器语言编写的程序程序称为目标程序,将高级语言编写的程序称为源程序,将源程序翻译成目标程序的程序称为编译程序。 2,软件危机:软件的正确性、开发成本、有错误而不能使用等。 3,对象是数据以及对数据进行简单的操作的封装体,程序设计语言的功能:数据表达和数据处理…

    C语言 2023年4月18日
    00
  • 浅析操作系统中的虚拟地址与物理地址

    浅析操作系统中的虚拟地址与物理地址 什么是虚拟地址与物理地址 在操作系统中,虚拟地址与物理地址是指计算机在执行程序时,CPU所看到的地址与实际存在于内存中的地址。 虚拟地址是程序使用的地址空间,是指编译器在编译程序的时候生成的地址空间,每个程序都有自己的虚拟地址空间。 物理地址则是实际在内存中的地址空间,是指计算机硬件所使用的地址空间,操作系统运行时,使用虚…

    C 2023年5月23日
    00
  • 深入解析C语言中的内存分配相关问题

    深入解析C语言中的内存分配相关问题 概述 在C语言中,内存分配是至关重要的。这是因为在C语言中,程序员需要手动地分配和释放内存以存储数据。C语言提供了几种内存分配方式,包括数据段、栈和堆。使用不当的内存分配方法可能导致程序运行时出现各种严重的问题,例如内存泄漏和段错误。本攻略将重点介绍C语言中的内存分配方式,并提供一些示例以帮助您更好地理解内存分配的概念。 …

    C 2023年5月23日
    00
  • C语言实现班级成绩管理系统

    C语言实现班级成绩管理系统 系统设计 班级成绩管理系统需要实现的功能包括学生信息的录入、成绩的录入、成绩的查询等,因此我们需要设计以下的数据结构: 学生信息 我们需要记录每个学生的学号、姓名和班级信息,因此我们可以使用如下的结构体定义: typedef struct student { char id[20]; char name[20]; char cla…

    C 2023年5月23日
    00
  • CCleaner如何修复注册表 CCleaner修复注册表教程

    CCleaner如何修复注册表 CCleaner是一款功能丰富、广受用户欢迎的免费系统清理和优化工具,其中修复注册表功能可以清理无用的注册表项,帮助优化电脑性能。下面介绍CCleaner如何修复注册表。 步骤1:打开CCleaner 首先,下载并安装CCleaner软件,并打开该软件。 步骤2:选择注册表 点击左侧的“注册表”选项卡。(注:在使用注册表工具时…

    C 2023年5月23日
    00
  • R语言的一个加法函数使用介绍

    当使用R语言进行数据分析和可视化时,经常需要编写一些自定义函数来增强数据操作的效率和可重复性。这里我为大家介绍一个R语言的加法函数,帮助大家了解如何自定义函数并灵活运用。 函数定义 首先定义一个简单的加法函数,用于计算两个数的和。 add <- function(x, y) { return(x + y) } 这里使用了R语言的函数声明语法,将函数名设…

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