【问题标题】:Special queue with defined size具有定义大小的特殊队列
【发布时间】:2012-11-21 19:07:57
【问题描述】:

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

这是最初的队列: 6 3 9 2

如果我往里面推东西,它必须在开头添加它,删除最后一个元素并返回它的值,所以,如果我添加 3 它将变成:

3 6 3 9 并返回 2

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

【问题讨论】:

  • 在满负荷之前应该返回什么?
  • FYI 添加到开头并从结尾删除称为 FIFO - 先进先出
  • 如果队列没有达到容量会发生什么,或者必须按容量构造?
  • 它必须以指定的容量构造,然后用零填充

标签: c# stack queue


【解决方案1】:
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();
    }
}

【讨论】:

    【解决方案2】:
    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();
        }
    }
    

    【讨论】:

    • 您应该真正使用Queue 来实现底层实现。从List 的开头删除是一种低效的操作。从逻辑上讲,将固定大小的队列包装成常规队列也是合乎逻辑的。哦,您可能不应该允许动态更改容量;我会在一开始就修复它。
    • @Servy 是的,刚想到,Dequeue 将是一个 O(n) 操作,改为 LinkedList 作为底层结构。
    • 为什么使用LinkedList作为底层结构?在一般情况下,这将比Queue 表现得差很多。 Queue 在下面实现为一个循环数组,它将使用 LinkedList 的一半内存并提供内存局部性,这可以显着提高搜索速度,并减少垃圾收集的工作量。 LinkedList,老实说,实际用途很少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多