我对我班级项目的表现有疑问。
我通过阅读文本文件形成了大约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)
差。
[编辑] 希望这有点澄清了我的帖子。
答案 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)
,所以你肯定会因为使用树而失去性能(更不用说内存了)。