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