C# 具有定义大小的特殊队列

C# 具有定义大小的特殊队列,c#,stack,queue,C#,Stack,Queue,我需要一个大小有限的收藏。它必须类似于循环缓冲区。我认为最快的描述方式是举个例子。假设我有一个“特殊”队列的实例,大小为4 这是最初的队列: 63992 如果我将某个元素推入其中,它必须在开头添加它,删除最后一个元素并返回其值,因此,如果我添加3,它将变成: 3 6 3 9并返回2 我希望我已经清楚了。。。 一个通用的实现就足够了,但是一个C实现将是最好的:)公共类MyQueue { 专用队列; 公共MyQueue(整数容量) { 容量=容量; 队列=新队列(容量); } 公共整数容量{get;

我需要一个大小有限的收藏。它必须类似于循环缓冲区。我认为最快的描述方式是举个例子。假设我有一个“特殊”队列的实例,大小为4

这是最初的队列: 63992

如果我将某个元素推入其中,它必须在开头添加它,删除最后一个元素并返回其值,因此,如果我添加3,它将变成:

3 6 3 9并返回2

我希望我已经清楚了。。。 一个通用的实现就足够了,但是一个C实现将是最好的:)

公共类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();
    }
}