【问题标题】:Binary Search Tree vs a MultiMap二叉搜索树与 MultiMap
【发布时间】:2012-12-11 19:22:00
【问题描述】:

我必须解决的问题是,我必须在树中输入 IP 地址前缀以及与它们关联的数据,以便以后可以查询它们。我正在从一个文件中读取这些地址,该文件可能包含多达 1600 万条记录,并且该文件可能有重复项,我也必须存储这些地址。

我编写了自己的二叉搜索树,但了解到 Java 中的 TreeMap 是使用红黑树实现的,但 TreeMap 不能包含重复项。

我希望查询花费O(logn) 时间。
数据结构需要在 Ram 中,所以我也不确定我要如何存储 1600 万个节点。

我想问:使用像番石榴这样的库在多地图中插入 Ips 会不会对性能造成太大影响?还是有更好的方法来做到这一点?

【问题讨论】:

  • 查找尝试。它们广泛用于 IP 路由。这将有所帮助:drdobbs.com/windows/fast-ip-routing-with-lc-tries/184410638
  • TreeMap 和 Guava 的 Multimap 都不允许使用前缀。无论它们是通过树还是哈希表实现的,它们都不允许诸如“查找最长包含的前缀 1.2.3.4”之类的事情;至少不是直接的(NavigableMap 可以在这里提供帮助)。

标签: java data-structures guava binary-search-tree memory-efficient


【解决方案1】:

使用经过测试记录且维护良好的内置库通常是一种好习惯。
它还将帮助您了解有关番石榴的更多信息。一旦您开始“只为一件事”使用它,您很可能会意识到还有很多东西可以让您的生活变得更轻松。

另外,另一种方法是使用 TreeMap<Key,List<MyClass>> 而不是 TreeMap<Key,MyClass> 作为 Multimap 的自定义实现。


关于内存 - 你应该尽量减少你的数据(使用高效的数据结构,不需要“浪费”String,例如用于存储 IP,有更便宜的替代方案,利用它们。

另请注意 - 操作系统将能够通过使用virtual memory 为您提供比您拥有的 RAM 更多的内存(实际上对于 64 位机器 - 它很可能已经足够了)。但是,它的效率很可能不如磁盘专用的 DS(例如 B+ trees)。


替代方案:
作为TreeMap 的替代品 - 您可能对其他数据结构感兴趣(每种都有其优点和缺点):

  • hash table - 在 java 中实现为 HashMap。然后您的类型将是HashMap<Key,List<Value>>。它允许O(1) 平均情况查询,但可能衰减到O(n) 最坏情况。它也不允许高效的范围查询
  • trie 或其更节省空间的版本 - radix tree。允许O(1) 访问每个键,但通常的空间效率低于替代方案。使用这种方法,您将使用 DS 实现 Map 接口,您的类型将为 Map<Key,List<Value>>
  • B+ tree,它更适合磁盘 - 如果您的数据太大而无法放入 RAM。

【讨论】:

  • 谢谢,当我执行查询时,我仍然可以使用多地图或 TreeMap> 获得 logN 性能吗?
  • @lts:是和不是。它将是O(logN),其中N 的数量,但迭代值列表或查找其中之一将取决于该特定列表的大小及其排列方式.您可以随时使用TreeMap<Key,Set<MyClass>> - 如果您还想快速搜索每个值列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
相关资源
最近更新 更多