2024王道408数据结构 P82 T1
思考过程
- 这题也比较基础哦,要求用tag来区分队列状态是空还是满,给了队头指针和队尾指针让我们写出入栈和出栈的算法。soeasy!
- 首先我们先假设出循环队列长这个样子,队头指针和队尾指针指向同一个地方,0 1 2 3 4 5 6 7是它的下标tag=0此时队列为空,在入栈前我们要判断队列是否为满,
if (Q.f==Q.s && Q.tag==1) return -1;
当队头指针和队尾指针相遇并且tag为1时就表示此时队满,我们就返回-1表示不能再往里面放元素了。 - 现在我们要开始入栈了,当我们把一个元素(假设是x1)入栈后
Q.data[Q.r]=x1
,此时队头指针f不动,队尾指针r往后移,Q.r=(Q.r+1)%MAXSIZE
模上元素个数是因为这是一个循环队列,只有%MAXSIZE才能把队头和队尾连起来,并且把Q.tag赋值为1,此时我们就已经成功入栈一个元素了。
- 我们一直往里面入栈元素直到队满,可以看到当我们入栈到第八个元素x8时,队尾指针r就和队头指针f指向同一位置了。
- OK接下来我们进行出栈操作,在进行出栈操作之前同样要先考虑是否队空,
if (Q.f == Q.s && tag == 0) return -1;
当队尾指针和队头指针指向同一位置并且tag值为0时,此时队列为空,不能再进行出栈操作。 - 如果队列不为空则可以正常进行出栈操作,出栈时我们把出栈元素保存起来,
x = Q.data[Q.f];
注意出栈时要移动的是队头f指针,Q.f=(Q.f+1)%MAXSIZE;
同样也要模上MAXSIZE,并且记得把tag值改成0。当我们删除x1时,移动f指针到下一个位置
此时队尾指针r也是不动的。此时出栈操作也大功告成了!
- 我们一直进行出栈操作直到队空,当我们删除到x8元素时,队头指针和队尾指针再一次指向同一位置。
完整代码如下
//
// Created by 黎圣 on 2023/7/30.
//
#include "iostream"
//这个MAX元素个数只是我举的例子
#define MAX 10
struct Queue
{
int data[MAX];
int f, r, tag;
};
//入栈操作
int EnQueue(Queue &Q, int x)
{
//先判断是否队满
if (Q.f == Q.r && Q.tag == 1)
{
printf("队满,入队失败\n");
return -1;
}
Q.data[Q.r] = x;
//这个打印不用写出来,只是我为了方便观察所以打印出来
printf("%d ", Q.data[Q.r]);
Q.r = (Q.r + 1) % MAX;
Q.tag = 1;
return 1;
}
//出栈操作
int DeQueue(Queue &Q, int x)
{
//判断是否队空
if (Q.f == Q.r && Q.tag == 0)
{
printf("队空,出队失败\n");
return -1;
}
x = Q.data[Q.f];
Q.f = (Q.f + 1) % MAX;
Q.tag = 0;
return 1;
}
int main()
{
Queue Q;
Q.f = 0, Q.r = 0, Q.tag = 0;
for (int i = 0; i < 10; i++)
EnQueue(Q, i);
printf("\n");
EnQueue(Q, 0);
for (int i = 0; i < 10; i++)
DeQueue(Q, i);
DeQueue(Q, 1);
return 0;
}
ok最后感谢b站up主@吸血小金鱼