数据结构之顺序队列(C语言基本操作及代码)

本文详细介绍顺序队列的基本概念,包括队列的定义、队头队尾操作原理,以及seqqueue.h和seqqueue.c中的关键函数如创建、入队、出队等。通过实例代码演示了如何使用C语言实现一个长度为6的顺序队列并处理满、空状态检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一,队列的基本概念

二,seqqueue.h头文件

三,seqqueue.c文件

1.创建空顺序队列

         2.入队

         3.出队

四,详细代码


一,队列的基本概念

    队列(queue),顾名思义,就像人们排队做核酸一样,先来排队的人,先做完核酸;后来排队的人,后做完核酸。由此可得队列定义:

                队列是只允许在一端进行插入操作,在另一端进行删除操作的线性表 

    我们称只允许插入的一头叫队尾,只允许删除的一头叫队头(进入队伍要在队尾进入,离开队伍要在队头离开)。所以,在结构体中,需要有一个指向队头的头指针(front)和一个指向队尾(rear)的尾指针,根据顺序存储的特点,还需要一个固定长度(N)的数组(data[N])来保存队列中每一个节点的数据。

    进一步思考,假设队列长度N为5,我们将队列围成一个圈

    为什么队列长度为5,要把圆圈分成六份呢,下面有简单解释;

    队列为空时,头指针front和尾指针rear都位于0,也就是都位于同一个位置;

    入队时,每插入一个数据,rear都会向后移动一位,指向插入节点的后一位,front保持不动;例如:向下标0处插入数据,rear移动到下标1处,向下标1处插入数据后,rear移动到下标2处,最终,当队列满时,rear移动到下标5处,至此不能继续插入数据,队列长度为6,只能插入5个数据。

    出队时,每输出一个数据,front都会向后移动一位,rear保持不动;

    队列满了之后,输出一个数据,下标0空出,所以此时继续输入数据时,rear继续移动到下标0,数据插入到下标5的位置;

    当front=rear时,队列中数据全部输出,队列变为空;

    计算长度和判断队列为满时,不考虑特殊情况,我们可以简单理解为队列长度=rear-front;队列为满=rear+1=front;

    但是,当rear刚好等于5,或者rear小于front时,上面的公式是不成立的,所以我们可以通过取余来得出通用公式:

    队列长度:(rear-front+N)%N;

    队列为满:(rear+1)%N=front;

    队列为空:rear=front;

 二,seqqueue.h头文件

#ifndef _SEQQUEUE_H_
#define _SEQQUEUE_H_
#include <stdio.h>
#include <stdlib.h>

#define N 6
typedef int datatype;
typedef struct 
{
    datatype data[N];
    int front;//队头下标
    int rear;//队尾下标
}sequeue_t;

//1.创建空顺序队列
sequeue_t *CreateSequeue(void);
//2.入队
int IntoSequeue(sequeue_t *p,datatype data);
//3.判断是否满
int isFullSequeue(sequeue_t *p);
//4.出队
datatype OutSequeue(sequeue_t *p);
//5.判断是否空
int isEpSequeue(sequeue_t *p);
//6.计算队列长度
int LengthSequeue(sequeue_t *p);
//7.清空队列
void ClearSequeue(sequeue_t *p);
#endif

三,seqqueue.c文件

1.创建空顺序队列

    空队列的创建非常简单,首先开辟结构体的内存,内存中包括一个长度为6的数组,一个front头指针和一个尾指针;

    创建成功后,对front和rear赋值为0,表示当前队列为空;

    最后将创建内存的首地址返回主函数中。

//1.创建空顺序队列
sequeue_t *CreateSequeue(void)
{
    //堆区开辟空间,结构体指针指向空间首地址;
    sequeue_t *p = (sequeue_t *)malloc(sizeof(sequeue_t));
    //判断是否创建成功;
    if(NULL == p)
    {
        printf("Create Sequeue fail\n");
    }
    //队首和队尾都等于下标0
    p->front = 0;
    p->rear = 0;
    //返回开辟的堆区空间首地址
    return p;
}

2.入队

    入队就是按顺序插入数据,让数据一个一个在队列中排好队;

    数据未出队之前,front一直处于下标0的位置,所以入队时,我们只需对rear进行操作,每次入队,都将数据插入到rear所在位置,插入后,将rear向后移动一位;

    为了避免rear向后移动时,出现rear等于6(队列长度N为6)的情况,我们需要对rear后移的操作进行修改:

                                               rear = (rear+1) % N;    

//2.入队
int IntoSequeue(sequeue_t *p,datatype data)
{
    //1.判断队列是否已满
    if(isFullSequeue(p))
    {
        printf("Into Sequeue fail\n");
        return -1;
    }
    //2.将数据插入到rear的位置
    p->data[p->rear] = data;
    //3.rear向后移动
    p->rear = (p->rear+1) % N;
    return 0;
}

3.出队

    出队,就是将数据输出,并将该位视为空位,等待新数据输入;

    出队的操作和入队的操作大体相同,首先将front所在位置的数据保存,然后将front向后移动,将后一位的数据作为队头,然后将出队的数据返回到主函数;

    同样,为避免出队时front出现等于6的情况,我们也需要对front的后移操作进行修改:

                                                    front = (front+1) % N;    

//4.出队
datatype OutSequeue(sequeue_t *p)
{
    //判断队列是否为空
    if(isEpSequeue(p))
    {
        printf("Out Sequeue fail\n");
        return -1;
    }
    //将要出队的数据保存
    datatype a = p->data[p->front];
    //front向后移动一位
    p->front = (p->front + 1) % N;
    return a;
}

四,详细代码

#include "seqqueue.h"

//1.创建空顺序队列
sequeue_t *CreateSequeue(void)
{
    //堆区开辟空间,结构体指针指向空间首地址;
    sequeue_t *p = (sequeue_t *)malloc(sizeof(sequeue_t));
    //判断是否创建成功;
    if(NULL == p)
    {
        printf("Create Sequeue fail\n");
    }
    //队首和队尾都等于下标0
    p->front = 0;
    p->rear = 0;
    //返回开辟的堆区空间首地址
    return p;
}
//2.入队
int IntoSequeue(sequeue_t *p,datatype data)
{
    //1.判断队列是否已满
    if(isFullSequeue(p))
    {
        printf("Into Sequeue fail\n");
        return -1;
    }
    //2.将数据插入到rear的位置
    p->data[p->rear] = data;
    //3.rear向后移动
    p->rear = (p->rear+1) % N;
    return 0;
}
//3.判断是否满
int isFullSequeue(sequeue_t *p)
{
    return (p->rear+1)%N == p->front;
}
//4.出队
datatype OutSequeue(sequeue_t *p)
{
    //判断队列是否为空
    if(isEpSequeue(p))
    {
        printf("Out Sequeue fail\n");
        return -1;
    }
    //将要出队的数据保存
    datatype a = p->data[p->front];
    //front向后移动一位
    p->front = (p->front + 1) % N;
    return a;
}
//5.判断是否空
int isEpSequeue(sequeue_t *p)
{
    return p->rear == p->front;
}
//6.计算队列长度
int LengthSequeue(sequeue_t *p)
{
    return (p->rear - p->front + N) % N;
}
//7.清空队列
void ClearSequeue(sequeue_t *p)
{
    /* 
    while(!isEpSequeue(p))
    {
        OutSequeue(p); 
    }
    */
   p->front = p->rear = 0;
}

    如果本文中存在代码逻辑,代码完善,解释不通或不清楚的错误,还请批评指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值