【发布时间】:2019-04-20 06:58:06
【问题描述】:
我有一个没有重复的项目列表,其中订单很重要。
我需要定期从该列表中删除一个项目。
一个实际的例子是列表绑定 UI 控件,例如允许删除的 DataGridView。
用户希望以特定顺序查看项目,因此删除后剩余的项目应保留其顺序。
这里有一些示例代码似乎表明删除列表项是O(n),因为
(1) 必须迭代列表以通过匹配条件找到要删除的项目
(2)List.RemoveAt 方法必须将剩余的项打乱
public class Item
{
public string Name {get; set;}
public string Description {get; set;}
}
public List<Item> Items = new List<Item>();
public void AddItem(string name, string description)
{
Items.Add(new Item {Name=name, Description=description});
}
public void RemoveItem(string name)
{
for (int i=0; i<Items.Count; i++)
{
if (Items[i].Name == name)
{
Items.RemoveAt(i);
break;
}
}
}
有没有更快的方法?
LinkedList<T> 不起作用,因为它不能被索引以进行滚动和分页。同样对于高项目计数LinkedList<T> 由于缓存未命中,项目删除实际上更慢。
【问题讨论】:
-
你不能从你正在迭代的集合中删除项目,你会得到一个异常
-
您是否需要能够使用
Items[someNumber]才能访问该列表?如果是这样,切换到LinkedList<T>可以让您在删除列表中的任意项目时获得更好的性能。 -
您的删除意味着搜索和删除。数组的搜索复杂度(列表是某种)是 O(n)。如果您需要较低的复杂性,则需要另一种数据结构(例如,保留项目名称以快速访问项目的字典)。
-
我需要保留原来的订单项目被添加到列表中。我想我可以使用
SortedDictionary<int,Item>,但这似乎有点矫枉过正并且会增加开销。 -
为什么
LinkedList<T>会提高性能?看来您仍然需要进行线性扫描,所以它是O(n)。