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;
}