我需要存储一组节点:
class Node
{
int Value;
//other info
}
我有三个要求:
我认为用于此的最佳集合将是某种排序列表。这样,通过从排序列表中获取第一个元素,可以有效地满足要求#1。通过在列表中的正确位置插入新节点,可以有效地满足要求#2。
但.Net中的SortedList
集合与SortedDictionary
类似,并且要求排序的密钥是唯一的,这违反了要求#3。
.Net中似乎没有满足这些要求的集合,主要是因为存在的自我排序集合要求按键排序是唯一的。这是什么原因?我认为这不是一个疏忽。我在这里没有抓到什么?我可以找到类似的问题,但他们通常会有人建议SortList
,然后意识到这不起作用,然后谈话在没有标准解决方案的情况下淡出。至少如果有人会说“C#中没有用于此任务的集合,你需要一起破解”,这将是一个答案。
是否可以使用常规List<Node>
并在添加新节点时重新排序列表?似乎不会像在正确的位置插入节点那样有效。也许这就是我应该做的?手动迭代列表,直到找到自己插入新节点的地方?
答案 0 :(得分:2)
如果您只需要有效插入并快速检索具有最低值的项目,那么您不需要排序列表。你需要一个heap。查看A Generic Binary Heap Class。
答案 1 :(得分:1)
通过添加对象ID或其他唯一标识符使list_key成为唯一:ID 4和5,两者都具有值“1”将变为“1_4”和“1_5”,可以毫无困难地添加到排序列表中按预期排序。
答案 2 :(得分:1)
您可以使用SortedList<int, List<NodeInfo>>
,您可以将Value
放在键中,将所有其他属性放在值中:
public class NodeList : SortedList<int, List<NodeInfo>>
{
public void Add(int key, NodeInfo info)
{
if (this.Keys.Contains(key))
{
this[key].Add(info);
}
else
{
this.Add(key, new List<NodeInfo>() { info } );
}
}
public NodeInfo FirstNode()
{
if (this.Count == 0)
return null;
return this.First().Value.First();
}
}
public class NodeInfo
{
public string Info { get; set; }
// TODO: add other members
}
以下是一些示例用法:
var list = new NodeList();
// adding
list.Add(3, new NodeInfo() { Info = "some info 3" });
// inserting
for (int i = 0; i < 100000; i++)
{
list.Add(1, new NodeInfo() { Info = "some info 1" });
list.Add(2, new NodeInfo() { Info = "some info 2" });
list.Add(1, new NodeInfo() { Info = "some info 1.1" });
}
// retrieving the first item
var firstNodeInfo = list.FirstNode();
// retrieving an item
var someNodeInfo = list[2].First();
答案 3 :(得分:0)
在我看来,使用普通列表并在每次插入后重新排序是可以接受的。排序在.NET中非常有效。请参阅此主题:String sorting performance degradation in VS2010 vs. VS2008
答案 4 :(得分:0)
您可以在OrderedMultiDictionary中使用Wintellect's Power Collections for .NET。这正是你要找的。 p>