我认为我的代码中的这一部分让我感到沮丧。如何更改它以便更快。我必须阅读战争和片断。它适用于较小的样本,但不会在不少于3小时的情况下阅读战争。
while (note.Count > 1)
{
// this is what I thing is taking the most time, because it loops through your note list, and builds a new list ordered by the node
// and it gets worse the longer the list is.
List<Node> orderedNodes = note.OrderBy(node => node.Frequency).ToList<Node>();
if (orderedNodes.Count >= 2)
{
// Takes the first two groups
List<Node> taken = orderedNodes.Take(2).ToList<Node>();
// Create greater node by combining the frequencies
Node parent = new Node()
{
Symbol = '*',
Frequency = taken[0].Frequency + taken[1].Frequency,
Left = taken[0],
Right = taken[1]
};
note.Remove(taken[0]);
note.Remove(taken[1]);
note.Add(parent);
}
this.trunk = note.FirstOrDefault();
}
答案 0 :(得分:3)
此代码具有最差的复杂度,如O(N *(N * 3 +(N * log N))) - 一目了然;确切的估计必须更糟。 实际上,它甚至可以在3个多小时内完成。 顺便说一句,它甚至完成了处理吗?
首先,通过使用以排序顺序维护节点的数据结构,以更有效的方式实现'note.OrderBy(node =&gt; node.Frequency)'的语义;或者想一想其他方法来防止在每一轮中重新排序整个列表,然后从中删除两个元素,然后添加另一个元素。
其次,在此代码中删除任何LINQ的痕迹。您对大型数据集进行了紧密循环,每轮都至少产生:
第三,确保'.Remove'和'.Add'采用常数或合理时间,但与物品数量不成线性比例。
然后,重新检查是否仍需要进一步优化。
开头的一些线索: