Java Big-O性能

时间:2011-03-09 19:10:45

标签: java time-complexity

我对我班级项目的表现有疑问。

我通过阅读文本文件形成了大约5000个游戏对象。我有一个Treemap(称为supertree),它作为节点Treemaps(我猜是迷你树图)。这些nodes/mini treemaps是动作,战略,冒险,运动,游戏标题等。基本上游戏类型和这些迷你树将保持游戏对象。因此supertree本身可能会持有8 nodes/treemaps

当我插入游戏对象时,它将确定它将进入哪个mini tree并将其放入其中。例如,如果我插入游戏超级马里奥世界,它将检查它是哪种类型并看到它是adventure,因此超级马里奥世界将被插入adventure树。

所以我的问题是,如果问题列出所有action games,那么性能会是什么,因为Treemap get是O(log n)

首先在超级树上,它将查找Action Node/Treemap,它将采用O(log n)。

然后一旦进入Action treemap,它会对所有o(n log n)正确的元素得到吗?

那么log n * (n * log n)的总体表现是否正确?哪个比o(n)差。

[编辑] 希望这有点澄清了我的帖子。

4 个答案:

答案 0 :(得分:5)

虽然supermap上的get是O(n_categories),但是通过另一个map(使用迭代器)应该是O(n_games)。如果n_categories的上限为10(因为添加新游戏时类别的数量不会改变),您可以假设超图查找为O(1)。

由于子图最多可以包含n_games条目(当所有条目都属于同一类别时),列出所有类型为action的游戏因此会给你O(n_games)。不要忘记,为了迭代所有条目,您不必每次都调用get()。这就像阅读一本书而不是翻页从第100页到第101页,从头开始计数并计入101 ...

编辑:由于上面的段落声明如果类别的数量是固定的,可以假设类别查找为O(1)似乎很难接受,让我说即使你坚持类别查找是O (log n_categories),仍然给出O(n_games),因为类别查找只需要进行一次。然后,迭代结果,即O(n_games)。这导致O(n_games + log n_categories)= O(n_games)。

答案 1 :(得分:4)

好的,首先,你的大O不会因语言而改变;这就是人们使用big-O(渐近)符号的原因。

现在,考虑一下你的整个算法。你拿出你的外树并获得每个元素,这确实是 O(n 0 lg n 0 。对于每个节点,您有 O(n 1 lg n 1 lg n 只有一个常数,所以它们可以组合在一起,你得到 O(n o ×n 1 lg n) O(n 2 lg n)

答案 2 :(得分:2)

关于OP分析的几条评论:

我假设您已经构建了树图/集,并且只是从已完成(预处理)的内存中表示中提取元素。

假设 n 是类型的数量。假设 m 是每种类型游戏的最大数量。

获得正确的“流派地图”的复杂性为O(lg n)(超级树的单get条)。在该类型中迭代游戏的复杂性取决于您的操作方式:

 for (GameRef g : submap.keySet()) {
   // do something with supermap.get(g)
 }

此代码会产生O(m)'获取'每个O(lg m)复杂度的操作,因此O(m lg(m))

如果你这样做:

for (Map.Entry e : submap.entrySet()) {
   // do something with e.getValue()
}

然后复杂性为O(m)循环迭代,并且对值进行恒定(O(1))时间访问。

使用第二个地图迭代方法,您的总复杂度为O(lg(n) + m)

答案 3 :(得分:-1)

呃,你是对的,直到最后一段。

您的总复杂度为O(n logn)logn用于查找类型,n列出该类型中的所有值。

如果您正在讨论列出所有内容,那么肯定不是O(n^2 logn),因为获取树中的所有值都是线性的。它将是O(n^2)

使用平面列表做同样的事情将是O(n logn),所以你肯定会因为使用树而失去性能(更不用说内存了)。