在Java中编写二维网格块时使用的最佳数据结构是什么?网格上的平铺应该可以通过它们的位置轻松引用,以便可以有效地计算邻居和路径。它应该是2D阵列吗?一个ArrayList?还有别的吗?
答案 0 :(得分:9)
如果你不太担心速度或内存,你可以简单地使用2D数组 - 这应该可以运行得很好。
如果速度和/或内存是您的问题,那么这取决于内存使用情况和访问模式。
如果您需要高性能,可以使用单维数组。您将正确的索引计算为y * wdt + x
。这有两个潜在的问题:缓存未命中和内存使用。
如果你知道你的访问模式是你大部分时间都在获取元素的邻居,那么如上所述将2D空间映射到1D数组可能会导致缓存未命中 - 你希望邻居在内存中关闭和来自2个不同行的邻居不是。您可能必须以不同的顺序将2d图块映射到1d阵列。例如,请参阅Hilbert curves。
为了更好地使用内存,如果您知道大部分图块始终相同(例如始终为草图),则可能需要实现sparse array或quad tree。两者都可以非常有效地实现,并考虑到缓存感知(稀疏数组链接就是这方面的好例子)。另一个好处是可以动态扩展这些。但是,为了实现这一点,您将始终必须支付额外的间接级别。
注意:如果您担心性能,请小心使用HashMap
等通用类,键类型为基本类型或特殊位置类 - 您每次都必须分配一个对象您索引哈希映射或支付装箱/拆箱的价格。除此之外,哈希映射将不允许您进行有效的空间查询(例如,给我存在于给定对象的半径R中的所有对象 - 四叉树对此更好)。
答案 1 :(得分:3)
如果网格具有固定尺寸,请使用2D数组。如果您需要动态大小,请使用ArrayLists的ArrayList。
答案 2 :(得分:2)
如果您计划将东西插入特定位置,那么2D阵列似乎是一个不错的选择。只要它固定大小。
答案 3 :(得分:2)
要使用的数据结构实际上取决于您将要执行的操作类型:
如果网格中有意义的位置(非零/非默认)的数量相当低(<< nxm ),则使用散列映射可能会更节省空间,映射(x,y)对特定图块的位置。此外,您可以更有效地迭代有意义的位置。此外,您可以将对相邻切片的引用存储到每个切片,以加快路径/邻域遍历。
如果您的网格密集地填充了“信息”,您应该考虑使用2d数组或ArrayList(如果您在某些时候将泛型类型作为“tile-type”涉及,则必须使用ArrayLists,因为Java确实如此)不允许泛型类型的原生数组)。
答案 4 :(得分:1)
如果你只需要迭代网格和单元格的随机寻址,那么MyCellType [] []应该没问题。对于这些用例,这在空间和(人们期望的)时间方面是最有效的。