我正在C#中寻找一个高效的数据结构,它允许我保留一份(由用户)订购的项目列表,而不会重复。
我的意思是由用户订购,即:
我需要在更改时在数据库中不断更新订单,以便我可以在开始时加载它。
我需要的操作:
所有这些操作都会频繁且同样重要。
答案 0 :(得分:6)
我认为“有效”是指渐近有效。如果情况并非如此,那么请澄清问题。
索引和任意插入的组合是一个棘手的问题。
List<T>
s - 它只是数组的一个薄包装 - 最后有O(1)插入/删除,开头有O(n)插入/删除,O(1)索引。检查唯一性是O(n)。没有符合您需求的单一数据结构。我的建议是:
这将为您提供O(1)唯一性检查和O(lg n)索引,插入和删除。
我注意到这个数据结构为你提供了O(1)个问题的答案“这个集合中的这个项目是什么?”但O(n)回答了“它在哪里?”的问题。因此,如果您需要快速进行逆索引操作,那么您手上的问题会更大。
答案 1 :(得分:1)
I think I would just use a List and take O(n) Contains or a separate HashSet for uniqueness. List does all the other stuff nicely. Nicely as the operations are all there but most will be O(n). Even on 10,000 O(n) is pretty fast. The database calls are going to be the slowest part by far (try async).
class MyCollection<T> : IList<T>
{
private readonly IList<T> _list = new List<T>();
public void Insert(int index, T item)
{
if (this.Contains(item))
throw new IndexOutOfRangeException();
_list.Insert(index, item);
//make database call
}
// implement all the other features of IList with database calls
答案 2 :(得分:1)
这有两个问题:一个用于数据库层,另一个用于内存中集合。但是,如果你让数据库层成为你的真相来源,我认为你几乎可以把它归结为一个问题。
我之所以这样说是因为大约有100个项目作为列表中活动项目的最大可能数量,您几乎可以忽略渐近的复杂性。在性能方面,当您获得这么多项目时,最重要的是跨越网络连接(例如,到数据库)的往返行程。
这是一个你可以使用的相当简单的方法。它类似于我过去所做的事情,具有类似的要求。 (我不记得它是否完全一样,但足够接近。)
Order
列确定给定列表中商品的顺序。 int
应该没问题。UPDATE
语句来完成。您可能希望使用存储过程在单独的往返过程中完成更多此项工作。绝对是避免竞争条件的交易。
这样的方法可以轻松扩展个别用户编辑单个列表。如果您需要并发用户的可扩展性,那么像NoSQL商店这样的另一种策略可能会成为可能。如果您需要扩展编辑同一列表的许多并发用户,事情变得非常复杂,您可能需要实现消息总线和其他优点。如果您发现需要扩展到列表中的数万个项目,则需要重新考虑UI以及它与服务器的通信方式(例如,您不希望将整个列表加载到记忆)。但是,当每个操作都是由用户手动执行时,担心内存中的数据结构并不能让您在任何这些情况下都能达到目标。
答案 3 :(得分:0)
就数据结构而言,假设你有直接引用节点,linked list对插入和删除的速度很快(在这种情况下,你需要一个双向链表) 。我还没有使用内置的.NET LinkedList
,但它似乎有some efficiency problems。如果您遇到List
问题,则可能只想使用正常的LinkedList
(实际上取决于&#34;效率&#34;您需要这样做。)请参阅List
时间复杂性here
至于保存它,您需要做的就是将索引保存在数据库中,并从启动时ORDER BY
的查询中填充您的集合。
编辑:
对于重复管理,您可以维护HashSet以检查重复项并阻止插入。