有没有更好的方法为队列实现Remove方法?

首先,只是授予我实际上想要Queue – FIFO的function,通常只需要Enqueue / Dequeue等等 – 所以我更喜欢“你真正想要的”之外的答案是List “(我知道RemoveAt )。

例如,假设我有一个数据点的Queue dataToProcess ,需要按照它们到达的顺序进行处理。 然后定期有一些像这样的代码是有意义的:

 while (dataToProcess.Count > 0) { DataPoint pointToProcess = dataToProcess.Dequeue(); ProcessDataPoint(pointToProcess); } 

但是,无论出于何种原因,我们都会发现, 应该处理已添加到队列中的特定数据点。 那么如果有一种类似于以下的方法,那将是理想的:

 dataToProcess.Remove(badPoint); 

我理解,实际上没有可行的方法来使用不涉及某种forms的枚举的Remove方法; 但是,由于Queue并不能让你随便进入并随机删除一些项目,我能想到的唯一解决方案是:

 bool Remove(T item) { bool itemFound = false; // set up a temporary queue to take items out // one by one Queue receivingQueue = new Queue(); // move all non-matching items out into the // temporary queue while (this.Count > 0) { T next = this.Dequeue(); if (next.Equals(item)) { itemFound = true; } else { receivingQueue.Enqueue(next); } } // return the items back into the original // queue while (receivingQueue.Count > 0) { this.Enqueue(receivingQueue.Dequeue()); } return itemFound; } 

这太荒谬了吗? 它当然看起来很糟糕,但除了编写自定义类之外,我无法真正看到更好的方法。 即便如此,我认为实现Remove方法的最佳方法是在内部使用LinkedList

我认为切换到一个内部具有LinkedList的新自定义类只需要几分钟时间,并且比现在的性能更高。

 public class SpecialQueue { LinkedList list = new LinkedList(); public void Enqueue(T t) { list.AddLast(t); } public T Dequeue() { var result = list.First.Value; list.RemoveFirst(); return result; } public T Peek() { return list.First.Value; } public bool Remove(T t) { return list.Remove(t); } public int Count { get { return list.Count; } } } 

另一种方法是将项目留在队列中,并在从中读取时忽略它们。 就像是:

 T DequeueFiltered(HashSet ignored) { T item; while (ignored.Contains(item = Dequeue())) { ignored.Remove(item); } return item; } 

我是初学者但是我最近设法解决了相同(或非常相似)的问题。 我希望它有所帮助。

这是我们的队列:

 Queue dataToProcess = new Queue(); 

如果我们将所有入队项的副本放入哈希集(例如:

 HashSet pointsToProcess = new HashSet(); 

所以当排队元素时,我们也会向hashset添加相同的数据。

当事实certificate我们不需要元素时,我们将其从该hashset中删除

 pointsToProcess.Remove(element); 

所以当我们必须’使用’队列的下一个元素时,

我们检查是否真的需要处理它(如果它是hashset的成员),否则它必须被忽略,我们可以摆脱它,

 while (dataToProcess.Count > 0) { if pointsToProcess.Contains(dataToProcess.Peek()) { // processing data } else { // error message and dataToProcess.Dequeue(); } } 

请参阅c#将Remove(int index)方法添加到.NET Queue类

队列是最有效的排队结构,在列表数据结构上实现队列效率不高。

虽然没有内置方式,但是你不应该使用List结构或其他结构,IFF Remove不是经常运行的。

如果您通常入队并出列但只是偶尔删除,那么您应该能够在删除时负担队列重建。

请参阅两个简单扩展方法的链接

public static void Remove(this Queue queue, T itemToRemove) where T : class

public static void RemoveAt(this Queue queue, int itemIndex) where T : class

 var first = Q.Dequeue(); if (first.Id.Equals(deleteId)) return; Q.Enqueue(first); while (Q.Peek() != first) { var r = Q.Dequeue(); if(!r.Id.Equals(deleteId)) Q.Enqueue(r); }