我有一个大的 2D 网格,x-by-y。应用程序的用户将添加有关此网格上特定点的数据。不幸的是,网格太大而无法实现为大型 x×y 数组,因为运行它的系统没有足够的内存。
什么是实现这一点的好方法,以便只有添加了数据的点才存储在内存中?
我的第一个想法是创建数据点的 BST。诸如“(long)x<<32 + y”之类的散列函数将用于比较节点。
然后我得出结论,如果不平衡,这可能会降低效率,所以我想出了一个由可比较的 BST 分数组成的 BST 的想法。外部 BST 将根据 x 值比较内部 BST。内部 BST 将通过它们的 y 值来比较这些点(并且它们都将具有相同的 x)。因此,当程序员想要查看 (5,6) 处是否有一个点时,他们会在外部 BST 中查询 5。如果在该点存在内部 BST,那么程序员将在内部 BST 中查询 6。结果将被退回。
你能想出更好的方法来实现它吗?
编辑:关于 HashMaps:大多数 HashMaps 需要有一个用于查找的数组。有人会说“data[hash(Point)] = Point();” 设置一个点,然后通过散列找到该点以找到索引。然而,问题是数组必须是散列函数范围的大小。如果此范围小于添加的数据点总数,则它们将没有空间或必须添加到溢出中。因为我不知道要添加的点数,所以我必须假设这个数字会小于某个数量,然后将数组设置为该大小。同样,这会实例化一个非常大的数组(尽管如果假设数据点将少于 x*y,则它比最初的要小)。
正如一些人所提到的,看起来我想要的是一个 SparseArray。它们的实现方式是否类似于在 BST 中包含 BST?
Edit2: Map<> 是一个接口。如果我要使用地图,那么看起来 TreeMap<> 将是最好的选择。所以我最终会得到 TreeMap< TreeMap< Point> >,类似于人们提出的 Map< Map< Point> > 建议,这基本上是 BST 中的 BST。不过,感谢您提供的信息,因为我不知道 TreeMap<> 基本上是 BST 的 Java SDK。
Edit3:对于那些可能关心的人,选择的答案是最好的方法。首先,必须创建一个包含 (x,y) 并实现可比较的 Point 类。该点可能会通过类似 (((long)x)<<32)+y) 进行比较。然后将 TreeMap 每个点指向数据。搜索它是有效的,因为它位于平衡树中,因此 log(n) 成本。用户还可以使用 TreeMap.entrySet() 函数查询所有这些数据,或遍历这些数据,该函数返回一组点以及数据。
总之,这允许稀疏数组的空间高效和搜索高效的实现,或者在我的情况下,二维数组也可以有效地迭代。