为什么要用循环队列,及基础操作代码(c语言)~DS笔记④

队列

一种重要的数据结构。它常常和放在一起作比较,因为一个是先进先出,另一个是后进先出
什么意思呢?就好比你去排队买票,那你越早排,也就越早买到票。这就像队列结构。也就是’‘先进先出’’。
怎么实现呢?可能你会说做一个数组一个队头指针一个队尾指针
就像下面这样:

queue
没错,这就是一个队列了。
但是,一般队列不这么做,为什么?
比如我们有了新元素要入队,又有元素要出对,怎么办?
那应该是下图这样:
queue
看起来好像没什么毛病,可是一直这么出队,入队,再出队再入队,结果会怎样呢?
如下图:
queue
那么总有一天,队头指针会走到队尾。
也就是说,终有一天,队伍有效长度会为零
如下图:
queue
可能你要说,那每次出队后让所有元素前移一位不行?
可以是可以,但这就增加了代码的时间复杂度,是冗余的开销。
当然,理论上你还可以让队伍足够长,但这也是不现实,不合理的。
那怎么解决这个问题呢?
这就是我们经常用到的:

循环队列

换言之,一般队列的弊端在于,如果不进行前移操作,那么队列队头指针终会到头。
那如果我们的队列没有队尾呢?
没错,循环队列就是一个‘‘’’,当然,这是逻辑结构,实际的物理存储方式还是和数组一样的。
如下图:

1
比如我们有元素要入对:
2
比如我们有元素出队:
3
我们可以随性所欲的进行入队,出队操作,而不必担心数组长度了。
而无论是时间复杂度,还是空间复杂度,我们都没有多余的增长

循环队列(顺序存储)

初始设定:
#include<stdio.h>
#define MAXSIZE 20  //存储空间初始分配量
typedef int QElemType; //类型根据情况而定,这里设为int
typedef enum{ False = 0, True = 1 }Bool;
结构体:
typedef struct
{//循环队列的顺序存储结构
 QElemType data[MAXSIZE];
 int front;     //头指针
 int rear;  //尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;
基本操作:
访问:
Bool visit(QElemType c)
{//访问输出
 printf("%d ", c);
 return True;
}
遍历:
Bool QueueTraverse(SqQueue* Q)
{//队列遍历
 int i;
 i = Q->front;
 while (i != Q->rear)
 {//遍历队列
  visit(Q->data[i]);//访问输出
  i = (i + 1) % MAXSIZE;//下标i每次加一
 }
 puts("");
 return True;
}
初始化:
Bool InitQueue(SqQueue* Q)
{//初始化一个空队列Q
 Q->front = 0;
 Q->rear = 0;
 return True;
}
是否为空:
Bool QueueEmpty(SqQueue* Q)
{/* 若队列Q为空队列,则返回True,否则返回False */
 if (Q->front == Q->rear) /* 队列空的标志 */
  return True;
 else
  return False;
}
返回长度:
int QueueLength(SqQueue* Q)
{/* 返回Q的元素个数,也就是队列的当前长度 */
 return  (Q->rear - Q->front + MAXSIZE) % MAXSIZE;
}
入队:
Bool EnQueue(SqQueue* Q, QElemType e)
{
 if ((Q->rear + 1) % MAXSIZE == Q->front)/* 队列满的判断 */
  return False;
 Q->data[Q->rear] = e;/* 将元素e赋值给队尾 */
 Q->rear = (Q->rear + 1) % MAXSIZE;/* rear指针向后移一位置 */
 return True;
}
出队:
Bool DeQueue(SqQueue* Q, QElemType *e)
{
 if (Q->front == Q->rear)/* 队列空的判断 */
  return False;
 *e = Q->data[Q->front];//将队头元素赋给e
 Q->front = (Q->front + 1) % MAXSIZE;/* front指针向后移一位置 */
 return True;
}

谢观~
再加一句,这儿有一个我在栈那一篇就介绍过的一个网站,可以实现队列的可视化操作:
https://visualgo.net/zh/list
(在网页上面菜单栏选择队列)
(:з)∠)

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值