What is a Circular Queue?
队列是先进先出,而循环队列是正常队列的扩展版本,其中队列的最后一个元素连接到队列的第一个元素,形成一个圆。这些操作是基于先进先出原理进行的,也称为“环形缓冲区”。
在正常的 Queue 中,我们可以插入元素直到队列满为止。但是一旦队列满了,即使队列前面有空格,我们也不能插入下一个元素。
由于循环队列比较特殊,所以无法仅仅通过 front = rear 来判断队列是否队满。因为是一个圈,所以 front = rear 有可能是空也可能是满,所以要特殊处理,如果队列还剩一个空位置,就认为队满。 如下:
- 队空:front == rear
- 队满:(rear + 1) % arr.length == front
Implementing code
创建队列
public class ArrayQueue<T>
{
private T[] arr;
private int front = 0;
private int rear = 0;
public ArrayQueue(int capacity)
{
arr = new T[capacity + 1];
}
}
添加元素
public bool Offer(T value)
{
if ((rear + 1) % arr.Length == front)
return false;
arr[rear] = value;
rear = (rear + 1) % arr.Length;
return true;
}
弹出元素
public T? Poll()
{
if (IsEmpty())
return default(T);
T val = arr[front];
front = (front + 1) % arr.Length;
return val;
}
判断是否对空
public bool IsEmpty()
{
return front == rear;
}
判断是否队满
public bool IsFull()
{
return front == (rear + 1) % arr.Length;
}
Test Circular Queue
首先创建Test方法
[TestClass]
public class ArrayQueueTests
{
private readonly ArrayQueue<int> _arrayQueue = new(5);
[TestMethod]
public void TestIsEmpty()
{
Assert.IsTrue(_arrayQueue.IsEmpty());
}
[TestMethod]
public void TestOffer()
{
Assert.IsTrue(_arrayQueue.Offer(1));
}
[TestMethod]
public void TestPoll()
{
Assert.IsNotNull(_arrayQueue.Poll());
}
[TestMethod]
public void TestIsFull()
{
_arrayQueue.Offer(1);
_arrayQueue.Offer(2);
_arrayQueue.Offer(3);
_arrayQueue.Offer(4);
_arrayQueue.Offer(5);
Assert.IsTrue(_arrayQueue.IsFull());
}
}
执行测试命令
dotnet test --filter ClassName=Algorithm.Tests.ArrayQueueTests
输出
已通过! - 失败: 0,通过: 4,已跳过: 0,总计: 4,持续时间: 13 ms - Algorithm.Tests.dll (net7.0)