c#环形队列
上一章说到的数组模拟队列存在的问题,问题分析并优化
- 目前数组使用一次就不能用,没有达到复用的效果
- 将这个数组使用算法,改进成一个环形的队列
1.数组模拟环形队列
对前面的数组模拟队列的优化,充分利用数组。因此将数组看做是一个环形的。(通过去模的方式来实现即可)
分析说明:
- 尾索引的下一个为头索引时,表示队列满。即将队列容量空出一个作为约定,这个在做判断队列满的时候需要注意(rear+1)%maxsize==front 满
- rear==front 空
实现思路如下:
- front指针含义调整,front指向队列第一个元素。也就是array[front]就是队列的第一个元素。front初始值=0。
- rear变量的含义调整,rear指向队列的最后一个元素的后一个位置。因为希望空出一个空间作为约定。rear初始值=0。
- 当队列满时,条件是(rear + 1)% maxsize = front , 位满。(PS:rear +1是预留一个位置,不牺牲这个空间会导致无法判断队列空或者满,rear一直自增,也就是说rear是很有可能大于maxsieze的,比如maxsize=5,rear=10,因为rear被加到10,此时rear的实际位置是0。取模式保证党front为0时,rear+1取模为0与front相等)
- 当队列空是,条件是rear==front 。
- 有效的数据个数,(raer + maxsize - front)%maxsize。(为什么要取模,因为是环形同时有rear可能是最大的然后跑到最前面来;假如:rear=1,front=0,maxsize=10 再套入公式中 (1+10-0)%10=1 有效数据为1)
2.代码实现
public class CircleArrayQueue
{
//队列最大值
private int _maxSize;
//队列头部
private int _front;
//队列尾部
private int _rear;
//存储值的数组
private int[] _tempArray;
public CircleArrayQueue(int maxSize)
{
Console.WriteLine($"MaxSize : { maxSize }");
_maxSize = maxSize;
_tempArray = new int[_maxSize];
//front指向队列第一个元素
_front = 0;
//rear指向队列的最后一个元素的后一个位置
_rear = 0;
}
public bool IsFull()
{
return (_rear + 1) % _maxSize == _front;
}
public bool IsEmpty()
{
return _rear == _front;
}
/// <summary>
/// 有效数据个数
/// </summary>
/// <returns></returns>
public int Num()
{
return (_rear + _maxSize - _front) % _maxSize;
}
public void EnQueue(int val)
{
if (IsFull())
{
Console.WriteLine("队列已满,无法加入数据!");
return;
}
//直接插入数据
_tempArray[_rear] = val;
//_rear后移一位,这里必须考虑取模
_rear = (_rear + 1) % _maxSize;
}
public int DeQueue()
{
if (IsEmpty())
{
throw new Exception("队列是空的,无法取出数据!");
}
//这里需要分析出front是指向队列的第一个元素
//1.先把front对应的值保留到一个临时变量
//2.将front后移
//3.将临时保存的变量返回
var tempVal = _tempArray[_front];
_front = (_front + 1) % _maxSize;
return tempVal;
}
public void ShowAll()
{
if (IsEmpty())
{
Console.WriteLine("队列是空的!");
return;
}
Console.WriteLine("显示队列所有内容:");
for (int i = _front; i < _front + Num(); i++)
{
Console.Write($"{ _tempArray[i % _maxSize] }\t");
}
Console.WriteLine();
}
public void PeekFirst()
{
if (IsEmpty())
{
Console.WriteLine("队列是空的,无法取出数据!");
return;
}
Console.WriteLine($"查看第一个值:{ _tempArray[_front] }");
}
}
代码调用
class Program
{
static void Main(string[] args)
{
//MySparseArray sparseArray = new MySparseArray();
//sparseArray.Print();
try
{
CircleArrayQueue queue = new CircleArrayQueue(4);
queue.EnQueue(97);
queue.EnQueue(98);
queue.EnQueue(200);
queue.EnQueue(1000);
//查看第一个值
queue.PeekFirst();
//显示队列里所有的内容
queue.ShowAll();
//取出一个值
Console.WriteLine($"取出一个值:{ queue.DeQueue() }");
Console.WriteLine($"取出一个值:{ queue.DeQueue() }");
Console.WriteLine($"取出一个值:{ queue.DeQueue() }");
queue.PeekFirst();
queue.EnQueue(200);
queue.ShowAll();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
}
运行效果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述