C# 具有定义大小的特殊队列
我需要一个大小有限的收藏。它必须类似于循环缓冲区。我认为最快的描述方式是举个例子。假设我有一个“特殊”队列的实例,大小为4 这是最初的队列: 63992 如果我将某个元素推入其中,它必须在开头添加它,删除最后一个元素并返回其值,因此,如果我添加3,它将变成: 3 6 3 9并返回2 我希望我已经清楚了。。。 一个通用的实现就足够了,但是一个C实现将是最好的:)C# 具有定义大小的特殊队列,c#,stack,queue,C#,Stack,Queue,我需要一个大小有限的收藏。它必须类似于循环缓冲区。我认为最快的描述方式是举个例子。假设我有一个“特殊”队列的实例,大小为4 这是最初的队列: 63992 如果我将某个元素推入其中,它必须在开头添加它,删除最后一个元素并返回其值,因此,如果我添加3,它将变成: 3 6 3 9并返回2 我希望我已经清楚了。。。 一个通用的实现就足够了,但是一个C实现将是最好的:)公共类MyQueue { 专用队列; 公共MyQueue(整数容量) { 容量=容量; 队列=新队列(容量); } 公共整数容量{get;
公共类MyQueue
{
专用队列;
公共MyQueue(整数容量)
{
容量=容量;
队列=新队列(容量);
}
公共整数容量{get;私有集;}
公共整数计数{get{return queue.Count;}}
公共T排队(T项)
{
排队。排队(项目);
如果(queue.Count>容量)
{
return queue.Dequeue();
}
其他的
{
//如果希望它执行其他操作,例如返回'peek'值
//根据需要修改。
返回默认值(T);
}
}
公共T Peek()
{
return queue.Peek();
}
}
公共类固定队列:IEnumerable
{
私有链接列表;
公共整数容量{get;私有集;}
公共固定队列(整数容量)
{
这个。容量=容量;
_列表=新的LinkedList();
}
公共T排队(T项)
{
_列表。添加最后一个(项目);
如果(_list.Count>容量)
返回退出队列();
返回默认值(T);
}
公共T出列()
{
如果(_list.Count==0)
抛出新的InvalidOperationException(“空队列”);
变量项=_list.First.Value;
_list.RemoveFirst();
退货项目;
}
公共T Peek()
{
如果(_list.Count==0)
抛出新的InvalidOperationException(“空队列”);
返回_list.First.Value;
}
公共空间清除()
{
_list.Clear();
}
公共IEnumerator GetEnumerator()
{
返回_list.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回_list.GetEnumerator();
}
}
在达到容量之前,它应该返回什么?仅供参考,将添加到开头并从结尾删除称为FIFO-先进先出如果队列未达到容量,会发生什么情况,或者它必须以容量构建?它必须以指定的容量构建,然后用零填充。对于底层实现,您应该真正使用队列。从列表开始删除是一种低效的操作。在逻辑上,固定大小的队列作为常规队列的包装器也是有意义的。哦,您可能不应该允许动态更改容量;我会在一开始就修复它。@Servy是的,我刚刚想到,Dequeue
将是一个O(n)操作,更改为LinkedList
作为基础结构。为什么要使用LinkedList
作为基础结构?在一般情况下,这将比队列
的性能差得多<代码>队列
在下面实现为一个循环数组,它将使用链接列表
的一半内存,并提供内存位置,这将大大提高搜索速度,减少垃圾收集的工作量<老实说,code>LinkedList
,几乎没有什么实际用途。
public class MyQueue<T>
{
private Queue<T> queue;
public MyQueue(int capacity)
{
Capacity = capacity;
queue = new Queue<T>(capacity);
}
public int Capacity { get; private set; }
public int Count { get { return queue.Count; } }
public T Enqueue(T item)
{
queue.Enqueue(item);
if (queue.Count > Capacity)
{
return queue.Dequeue();
}
else
{
//if you want this to do something else, such as return the `peek` value
//modify as desired.
return default(T);
}
}
public T Peek()
{
return queue.Peek();
}
}
public class FixedQueue<T> : IEnumerable<T>
{
private LinkedList<T> _list;
public int Capacity { get; private set; }
public FixedQueue(int capacity)
{
this.Capacity = capacity;
_list = new LinkedList<T>();
}
public T Enqueue(T item)
{
_list.AddLast(item);
if (_list.Count > Capacity)
return Dequeue();
return default(T);
}
public T Dequeue()
{
if (_list.Count == 0)
throw new InvalidOperationException("Empty Queue");
var item = _list.First.Value;
_list.RemoveFirst();
return item;
}
public T Peek()
{
if (_list.Count == 0)
throw new InvalidOperationException("Empty Queue");
return _list.First.Value;
}
public void Clear()
{
_list.Clear();
}
public IEnumerator<T> GetEnumerator()
{
return _list.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _list.GetEnumerator();
}
}