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

yizhihongxing

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语言 continue语句

    当C语言程序执行到循环体内部时,某些情况下需要跳过当前循环,立即进入下一次循环,或者直接跳出循环继续执行下面的代码,这时可以使用continue语句来实现。 continue语句的使用方法如下: for (初始化; 条件表达式; 计数器更新) { if (满足条件) { continue; } // 循环体语句 } 当循环中满足某个条件时,continue语…

    C 2023年5月9日
    00
  • C 数据类型

    当我们使用 C 语言进行编程时,需要用到不同的数据类型来存储和操作不同的数据。C 语言中支持多种数据类型,包括整型、浮点型、字符型等。在本文中,我将详细讲解 C 数据类型的完整使用攻略,包括数据类型的定义、使用和常见问题等方面。 数据类型的定义 在 C 语言中,可用的数据类型包括基本数据类型和派生数据类型。 基本数据类型 C 语言中的基本数据类型包括整型、浮…

    C 2023年5月10日
    00
  • .Net行为型设计模式之策略模式(Stragety)

    .Net行为型设计模式之策略模式(Strategy) 策略模式概述 策略模式是一种行为型设计模式,它定义了一系列算法,并且将每个算法封装起来,使得它们可以互相替换。策略模式让算法的变化独立于使用它们的客户端。 策略模式的组成 策略模式由以下几个部分组成: Context:上下文对象,它持有一个具体策略的引用,并调用具体策略的算法。 Strategy:策略接口…

    C 2023年5月23日
    00
  • C程序 双指针技术

    C程序 双指针技术的完整使用攻略 双指针技术是C语言中常用的一种编程技巧,它通过利用两个指针的相对位置关系,实现快速查找、合并、移动等操作。下面详细讲解一下如何在C程序中使用双指针技术。 1. 双指针技术概述 双指针技术常用于数组操作、链表操作等场景。在使用双指针技术时,我们需要定义两个指针变量p和q,分别指向数组或链表中的元素。p和q可以指向同一个元素,也…

    C 2023年5月9日
    00
  • 深入理解Spring注解@Async解决异步调用问题

    下面我来详细讲解如何深入理解Spring注解@Async解决异步调用问题。 什么是@Async注解 Spring框架提供了@Async注解,该注解用于标记方法,表示该方法是异步的。当被标记的方法被调用时,它会在另外一个线程中运行,而不是阻塞主调线程。@Async注解使用在Spring中非常普遍,特别是在需要执行一些耗时的任务时,例如发送电子邮件、生成报告、下…

    C 2023年5月23日
    00
  • C语言数组和指针的差别

    当我们学习 C 语言时,经常会遇到数组和指针这两个概念。它们虽然有些相似的地方,但是它们还是有很大的区别的。 数组和指针的定义 数组是相同类型数据的集合,它们在内存中是连续存储的,可以通过数组名加索引的方式访问每个元素。 指针是一个变量,存储的是一个地址。这个地址指向的是另外一个变量的值,可以通过指针来访问和修改这个变量的值。 数组和指针的区别 数组的长度是…

    C 2023年5月9日
    00
  • c/c++中变量的声明和定义深入解析

    c/c++中变量的声明和定义深入解析 在c/c++中,变量的声明和定义是非常重要的,因为它们决定了变量的作用域和生命周期。本文将深入讲解变量声明和定义的概念、语法和使用方法,并提供两个实例进行说明。 变量声明和定义 在c/c++中,变量的声明和定义是不同的概念,虽然在一些情况下它们可以混用。下面分别介绍两者的概念、语法和使用方法。 变量声明 变量声明是指向编…

    C 2023年5月23日
    00
  • VC使用编译时间作为版本号标识的方法

    使用编译时间作为版本号标识的方法可以在软件版本变化时,方便的追踪和定位问题。下面是详细的攻略: 1. 在VC中设置编译时间宏 在VC的项目属性中,我们可以通过设置一个宏来获取编译时间。具体操作方法如下: 打开VC项目,右键单击项目,选择“属性”。 在左侧窗格中,选择“配置属性”->“C / C++”->“预处理器”。 在“预处理器定义”下,点击“…

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