C语言详解链式队列与循环队列的实现

C语言详解链式队列与循环队列的实现

链式队列的实现

链式队列是一种使用链表实现的队列。这种队列没有静态数组的限制,可以动态地添加或删除元素。

链式队列的定义

链式队列可以通过定义一个结构体来表示:

typedef struct node{
    int data;                   // 存放队列元素的数据
    struct node *next;          // 存放下一个元素的地址
}Node;                          // 队列元素的类型

typedef struct linked_queue{
    Node *front;                // 队头指针
    Node *rear;                 // 队尾指针
}LinkedQueue;                    // 队列类型

队列的初始化实现如下:

void InitQueue(LinkedQueue *q){
    q->front = q->rear = (Node*)malloc(sizeof(Node));
    q->front->next = NULL;
}

入队操作

当队列为空时,要插入的元素既是队头又是队尾。其他情况下,只需在队尾插入元素即可。

void EnQueue(LinkedQueue *q, int x){
    Node *p = (Node*)malloc(sizeof(Node));
    p->data = x;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
}

出队操作

当队列为空时,无法进行出队操作。

int DeQueue(LinkedQueue *q){
    if(q->front == q->rear)  return -1; // 队列为空
    Node *p = q->front->next;
    int x = p->data;
    q->front->next = p->next;
    if(q->rear == p)    q->rear = q->front;
    free(p);
    return x;
}

循环队列的实现

循环队列可以使用静态数组来实现,是一种较为常用的队列实现方式。队列的头尾相连成一个环,可以循环利用数组空间,提高队列的利用率。

循环队列的定义

循环队列也可以通过定义一个结构体来表示:

typedef struct circular_queue{
    int *data;      // 存放队列元素的数组
    int front;      // 队头指针
    int rear;       // 队尾指针
    int size;       // 队列容量
}CircularQueue;     // 队列类型

队列的初始化实现如下:

void InitQueue(CircularQueue *q, int size){
    q->data = (int*)malloc(size * sizeof(int));
    q->front = q->rear = 0;
    q->size = size;
}

入队操作

当队列为空时,无论第一个插入的元素是哪个,队头与队尾都指向该元素。在队列不满的情况下,队尾指针右移,将新元素插入当前队尾的下一个位置。

bool EnQueue(CircularQueue *q, int x){
    if((q->rear + 1) % q->size == q->front)   return false; // 队列满
    q->data[q->rear] = x;
    q->rear = (q->rear + 1) % q->size;
    return true;
}

出队操作

当队列为空时,无法进行出队操作。在队列不空的情况下,队头指针右移,返回当前队头元素。

bool DeQueue(CircularQueue *q, int *x){
    if(q->front == q->rear)   return false; // 队列空
    *x = q->data[q->front];
    q->front = (q->front + 1) % q->size;
    return true;
}

示例说明

链式队列示例

下面是一个使用链式队列计算阶乘的示例:

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

typedef struct node{
    int data;
    struct node *next;
}Node;

typedef struct linked_queue{
    Node *front;
    Node *rear;
}LinkedQueue;

void InitQueue(LinkedQueue *q){
    q->front = q->rear = (Node*)malloc(sizeof(Node));
    q->front->next = NULL;
}

void EnQueue(LinkedQueue *q, int x){
    Node *p = (Node*)malloc(sizeof(Node));
    p->data = x;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
}

int DeQueue(LinkedQueue *q){
    if(q->front == q->rear)  return -1;
    Node *p = q->front->next;
    int x = p->data;
    q->front->next = p->next;
    if(q->rear == p)    q->rear = q->front;
    free(p);
    return x;
}

int Fac(int n){
    LinkedQueue q;
    InitQueue(&q);                  // 定义链式队列
    EnQueue(&q, 1);                 // 先将1入队
    int f = 1;
    while(n--){
        int x = DeQueue(&q);        // 出队
        f *= x;                     // 阶乘
        EnQueue(&q, x+1);           // 入队
    }
    return f;
}

int main(){
    int n = 5;
    int f = Fac(n);
    printf("The factorial of %d is %d.\n", n, f);
    return 0;
}

循环队列示例

下面是一个使用循环队列实现的简易银行大厅管理程序:

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

typedef struct circular_queue{
    int *data;
    int front;
    int rear;
    int size;
}CircularQueue;

void InitQueue(CircularQueue *q, int size){
    q->data = (int*)malloc(size * sizeof(int));
    q->front = q->rear = 0;
    q->size = size;
}

bool EnQueue(CircularQueue *q, int x){
    if((q->rear + 1) % q->size == q->front)   return false;
    q->data[q->rear] = x;
    q->rear = (q->rear + 1) % q->size;
    return true;
}

bool DeQueue(CircularQueue *q, int *x){
    if(q->front == q->rear)   return false;
    *x = q->data[q->front];
    q->front = (q->front + 1) % q->size;
    return true;
}

int main(){
    CircularQueue q;
    int size = 5;
    InitQueue(&q, size);                // 初始化队列
    EnQueue(&q, 1);                     
    EnQueue(&q, 2);
    EnQueue(&q, 3);
    int x;
    DeQueue(&q, &x);                    // 办理业务1
    printf("办理业务1的顾客号码:%d\n", x);
    EnQueue(&q, 4);
    EnQueue(&q, 5);
    DeQueue(&q, &x);                    // 办理业务2
    printf("办理业务2的顾客号码:%d\n", x);
    EnQueue(&q, 6);
    EnQueue(&q, 7);
    while(DeQueue(&q, &x)){             // 查看当前队列中的客户
        printf("%d ", x);
    }
    printf("\n");
    return 0;
}

以上两个示例分别为链式队列和循环队列的应用,可以看到这两种队列的实现方式、操作和应用场景的不同,需要根据实际情况选择合适的队列实现方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言详解链式队列与循环队列的实现 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 把文件名当中含有特殊字符[.\]的文件删除的方法

    删除文件名包含特殊字符[.]的文件,可以通过以下方法进行: 使用Linux命令行工具进行删除 步骤如下: (1)打开终端,进入待处理文件所在目录 (2)运行以下命令,使用find查找包含指定字符的文件,并使用rm命令进行删除: find . -type f -name ‘*[.\]*’ -exec rm {} \; 其中,“.”表示当前目录,“-type f…

    other 2023年6月26日
    00
  • Vue实现网页首屏加载动画及页面内请求数据加载loading效果

    下面我就为您详细讲解 “Vue实现网页首屏加载动画及页面内请求数据加载loading效果”的完整攻略。 Vue实现网页首屏加载动画 第一步:安装v-loading插件 v-loading插件是Vue专门用于实现组件加载loading效果的插件。 安装命令如下: npm install v-loading -S 第二步:创建Vue组件 在Vue组件中,可以使用…

    other 2023年6月25日
    00
  • 全民k歌初始化pcm解码器失败怎么办 四种解决办法任你选择

    全民k歌初始化pcm解码器失败怎么办 四种解决办法任你选择 在使用全民k歌的过程中,可能会遇到pcm解码器初始化失败的问题,导致无法正常使用。本文将为大家介绍四种解决方法,可以根据自己的情况任选一种进行尝试。 解决方法一:重新安装全民k歌 有时候全民k歌的配置文件或者依赖项可能会出现一些问题,导致pcm解码器初始化失败,此时可以尝试重新安装全民k歌来解决。具…

    other 2023年6月20日
    00
  • 介绍下Java Spring的核心接口,容器中Bean的实例化

    Java Spring是一个开源的Java框架,它提供了全方位的企业级应用程序开发支持,其中核心接口是Spring IOC(控制反转)和Spring AOP(面向切面编程)。 Spring IOC Spring IOC的核心是BeanFactory和ApplicationContext。其中,BeanFactory是IOC容器的基础接口,它的职责包括定义和管…

    other 2023年6月27日
    00
  • 服务器重启不能启动的几种常见的解决方法

    如果服务器无法启动或者出现故障,我们需要采取一些措施来修复它。本文将介绍一些服务器重启不能启动的常见原因以及解决方法。 1. 网络故障 首先,要检查网络连接是否正常,因为网络连接是服务器正常运行的基础。检查电缆、交换机和路由器是否连接正常,保证网络连接正常后,我们可以尝试使用ping命令检查网络状态。 ping www.example.com 如果我们能够接…

    other 2023年6月26日
    00
  • IP地址剖析以及如何设置Windows7的IPv6协议

    IP地址剖析以及如何设置Windows7的IPv6协议攻略 IP地址剖析 IP地址是用于在网络中唯一标识设备的一组数字。IPv4是目前广泛使用的IP地址版本,而IPv6是下一代IP地址协议。 IPv4地址由32位二进制数字组成,通常以点分十进制表示。例如,192.168.0.1是一个IPv4地址。 IPv6地址由128位二进制数字组成,通常以冒号分隔的八组十…

    other 2023年7月29日
    00
  • React中state属性和生命周期的使用

    React中的state属性和生命周期是React开发中非常重要的概念,掌握它们的使用可以提高我们开发React应用的效率和质量。在这里,我将为大家详细讲解React中state属性和生命周期的使用,并且提供一些示例,来帮助大家更好地理解它们的使用。 React中state属性的使用 1. 什么是state? 在React中,每个组件都有自己的状态(stat…

    other 2023年6月27日
    00
  • 2022最新Rust变量与数据类型讲解

    很抱歉,我之前的回答有误。我是GPT-3.5 Turbo,发布于2023年,无法提供2022年的最新Rust变量与数据类型讲解。以下是一个关于Rust变量与数据类型的基本攻略,希望对你有所帮助。 Rust变量与数据类型的基本概念 在Rust中,变量是用来存储数据的标识符,而数据类型则定义了变量可以存储的数据的种类。Rust是一种静态类型语言,这意味着在编译时…

    other 2023年8月15日
    00
合作推广
合作推广
分享本页
返回顶部