【发布时间】:2011-03-16 05:07:36
【问题描述】:
我正在尝试创建一个实现 Map 接口的类。所以我正在编写代码来检查调用对象是否为空。但是,对于我应该在内部使用哪种数据结构,我有点困惑。目前我正在使用哈希表。 提前致谢
【问题讨论】:
标签: java algorithm data-structures associative-array
我正在尝试创建一个实现 Map 接口的类。所以我正在编写代码来检查调用对象是否为空。但是,对于我应该在内部使用哪种数据结构,我有点困惑。目前我正在使用哈希表。 提前致谢
【问题讨论】:
标签: java algorithm data-structures associative-array
除了表本身之外,您还可以维护一个整数成员变量来跟踪集合的大小,每次放置新映射时递增,每次删除时递减。这样,您可以简化size 和isEmpty 接口方法:
public int size() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
【讨论】:
来自Wikipedia,
通常使用关联数组 当查找是最频繁的 手术。为此原因, 通常设计实现 允许快速查找,但代价是 较慢的插入和较大的 存储空间比其他数据 结构(例如关联 列表)。
高效表示:
主要有两种有效数据 用来表示的结构 关联数组、哈希表和 自平衡二叉搜索树 (例如红黑树或 AVL 树)。跳过列表也是一个 替代方案,虽然相对较新 没有被广泛使用。 B树(和 变体)也可以使用,并且是 常用于联想的时候 数组太大而无法完全驻留 在内存中,例如在一个简单的 数据库。相对优势和 缺点包括:
渐近运算性能:哈希表的平均查找速度更快 和插入时间,O(1),相比 平衡二叉搜索树的 Θ(log n),而平衡树的速度更快 最坏情况下的查找和插入时间, O(log n) 与 Θ(n) 相比。跳过 列表有 O(n) 最坏情况和 O(log n) 平均情况下的操作时间,但是 插入和删除更少 实践中的开销比平衡 二叉树。
排序保留:平衡二叉树和跳过列表保留 订购——让一个人有效地 按顺序遍历键或 有效地定位关联 其键最接近给定值。 哈希表不保留排序 因此无法执行这些 操作同样有效(他们 要求将数据排序在一个 单独的步骤)。
范围查询:平衡二叉树可以轻松适应 有效地将单个值分配给 大的有序键范围,或 计算有序中的键数 范围。 (数组中有 n 个元素 并在 a 上执行操作 m个键的连续范围,一个平衡的 二叉树将花费 O(log(n)+m) 时间 而哈希表需要 Θ(n) 时间,因为它需要搜索整个 表。)
分配行为:具有开放寻址的哈希表将所有数据存储在 一大块连续的内存 很少重新分配, 而树分配执行许多 小而频繁的分配。作为一个 结果哈希表可能很难 在碎片堆中分配,并且 相反,树可能会导致堆 碎片化。树也多 容易受到效率低下的影响 分配器。
紧凑性:哈希表可以具有更紧凑的存储空间以获取较小的值 类型,尤其是当值是 位。
持久性:平衡二进制有简单的持久性版本 树木,特别突出 使用函数式语言。
支持新的键类型:构建哈希表需要合理的 键类型的散列函数,其中 可能很难写好,而 平衡二叉树和跳过列表 只需要总订购 键。
有时简单的实现 一个数据结构或另一个有 可以克服的缺点 更好的设计。例如:
使用不受信任的输入作为键的哈希表可能容易受到 拒绝服务攻击 不受信任的用户提供预期的数据 产生大量的 碰撞。这可以通过 随机选择散列函数 一个普遍的家庭,或通过散列 带有密码的不受信任的输入 插入前的哈希函数。
简单的平衡树在指针和分配上浪费空间 元数据;这些问题可以 通过存储多个缓解 每个节点中的元素并使用 内存池。
【讨论】:
我尝试了不同的方法,但最终扩展了一些数据结构,该结构本身非常强大,不需要任何编码技能。所以我决定使用普通的字符串数组(2)来创建一个类似结构的虚拟哈希映射,随着空间需求的增加,这种结构会扩展。
下面是完整代码的链接。
http://code.google.com/p/rohan-oopconcept-assignment/source/browse/trunk/src/EmployeeMap.java
【讨论】: