在LinkedList <t>上进行二进制搜索以将值插入到排序值列表的中间会增加性能吗?</t>

时间:2012-10-15 00:25:51

标签: .net performance linked-list binary-search sortedcollection

我需要创建一个排序列表,一次添加一个项目。所以我决定选择 LinkedList<T> ,因为它在插入操作中效率很高。但是当找到合适的位置时,似乎需要更长的时间。我正在使用线性搜索来获取位置。如果我使用二进制搜索来使用 ElementAt 方法获取正确的位置,它会提高性能吗?根据{{​​3}},它仍然是O(n)操作。你怎么看?如果是这样,那么工作还有其他更好的数据结构吗?因为如果我使用不同的数据结构,当向中间插入一个新值时,我将不得不将该位置之后的所有数据移动一个位置,这显然是不希望的。

2 个答案:

答案 0 :(得分:1)

你的问题有一些误解。

  

将对LinkedList进行二进制搜索,以便在中间插入一个值   排序值列表会提高性能吗?

二进制搜索仅对已排序的集合有意义。 LinkedList<T>不是一个。这是一个关于收集的插入顺序。在LinkedList<T>上执行二进制搜索:

  • 你必须对链表进行排序,这不仅非常低效(在链表上操作),而且仅仅是插入的工作量太多

  • 或者你必须通过插入正确的位置来保持插入时的排序顺序,这又是一个太多的工作。

从你的问题我理解的是你想要一个关于集合的排序顺序,但插入必须更快(不像O(n)特征,比如典型的List<T>)。我的建议是在.NET中使用已排序的集合类型。 system.dll中有一个SortedSet<T>。这不会让你有重复,因为它是一个集合,在这种情况下你可以implement a custom SortedBag<T> (or SortedList<T> or whatever name) as shown here

  

我使用线性搜索来获取位置。

我的建议是你不这样做。让集合本身找到执行插入的位置。排序的集合类型最适合这里。

  

如果我使用二进制搜索来使用ElementAt获取正确的位置   方法,它会提高性能

ElementAt方法不执行二进制搜索。它最好检查集合类型是否为IList<T>并相应地使用索引器。不,在你的情况下,它对性能没有任何影响。

  

当向中间插入一个新值时,我必须将该位置之后的所有数据移到一个位置,这显然是不希望的   

你是对的,插入像List<T>这样的基于数组的结构的中间是一个O(n)操作。我不确定你是否也需要索引操作,但这样会更昂贵。您可以使用具有高效插入的排序集合类型,这些插入没有索引感,或者您可以使用索引排序的集合类型,但插入将是O(n)。这是你必须支付的权衡。

答案 1 :(得分:0)

出于您的目的,使用SortedDictionary class (or perhaps SortedList)

可能会更好

SortedDictionary提供O(log n)插入和检索时间。