循环队列


title: 循环队列
date: 2020-10-22 21:14:05
tags: 循环队列
categories: 数据结构


循环队列,底层内存结构:静态数组

灵魂思想: 将指针的自增改为 指针 = (指针+ 1) % (数组的真实长度)

// 循环队列
// 为了区分空队列和满队列
// 在这里我们认为当整个数组只剩下队尾的那块空间时,队列已满
// 当对头和队尾相等时,列队空
// 因此 队列中成员个数的最大值是 MAX_SIZE - 1
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10
#define OVER_FLOW -99
typedef struct DuiLie
{
    int arr[MAX_SIZE];
    // front为队头
    int front;
    // pear为队尾
    int pear;
} Sql;
// 打印分割线
void DivideLine()
{
    printf("------------------------------\n");
}
// 队列的初始化
void InitSql(Sql *pSql)
{
    pSql->front = 0;
    pSql->pear = 0;
    for (int i = 0; i < MAX_SIZE; i++)
        pSql->arr[i] = i;
    pSql->front = 6;
    pSql->pear = 8;
    // 队头在6,队尾在3
}
// 从队头到队尾依次打印队列元素
void PrintSql(Sql sql)
{
    // 先判断是不是空队列
    if (sql.front == sql.pear)
    {
        printf("当前队列信息:空队列\n");
        printf("front下标为 %d, pear 下标为 %d\n", sql.front, sql.pear);
        DivideLine();
        return;
    }
    // 如果pear在front的前面那么说明现在是循环队列了
    int length = ((sql.pear - sql.front) + MAX_SIZE) % MAX_SIZE;
    printf("当前队列长度为 %d\n", length);
    printf("front下标为 %d, pear 下标为 %d\n", sql.front, sql.pear);
    printf("打印队列:\n");
    for (int i = 0; i < length; i++)
        printf("%d ", sql.arr[(sql.front + i) % MAX_SIZE]);
    printf("\n");
    DivideLine();
}
// 求队列长度
int GetLength(Sql sql)
{
    int length = (sql.pear - sql.front + MAX_SIZE) % MAX_SIZE;
    return length;
}

// 入队
void InSql(Sql *pSql, int inNumber)
{
    // 如果队尾+1 == 队头 即认为队列已满
    // 正常情况下队尾在队头的后面
    // 当循环队列的时候 队尾在队头的前面
    if (((pSql->pear + 1) % MAX_SIZE) == pSql->front)
    {
        printf("队列已满!\n");
        return;
    }
    // 入队的时候,上回的rear指向哪,就往哪里存元素
    pSql->arr[pSql->pear] = inNumber;
    // 入队的时候可能会从普通队列转换成循环队列
    // 当入队前pear表示数组的最后一个元素的下标时
    // 数组最后一个元素
    pSql->pear = (pSql->pear + 1) % MAX_SIZE;
}

// 出队
void OutSql(Sql *pSql, int *pOutNumber)
{
    // 先判断是不是空队列
    if (pSql->front == pSql->pear)
    {
        printf("空队列...出队失败!\n");
        exit(OVER_FLOW);
    }
    // 出队
    // 先将队头元素赋给传进来的变量
    *pOutNumber = pSql->arr[pSql->front];
    // 然后改变front表示的下标
    pSql->front = (pSql->front + 1) % MAX_SIZE;
}
int main(void)
{
    Sql sql;
    InitSql(&sql);
    PrintSql(sql);
    // 要传一个入队元素过去
    for (int i = 0; i < 8; i++)
    {
        InSql(&sql, i);
        PrintSql(sql);
    }
    int outNumber;
    for (int i = 0; i < 10; i++)
    {
        OutSql(&sql, &outNumber);
        printf("取出的队列元素为 %d \n", outNumber);
        PrintSql(sql);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值