因此,我认为 HashTable 是最适合使用的算法,因为它只是生成关键对象的散列,并使用它来访问目标数据——它是 O (1)。其他的是 O (N)(大小为 N 的链表——你必须一次迭代一个链表,平均 N/2次)和 O (log N)(二叉树——你在每次迭代中将搜索空间减半——只有在树是平衡的情况下,所以这取决于你的实现,一个不平衡的树可能会有明显更差的性能)。
如果二叉树是 平衡,那么二叉树只有 O (logn)查找和插入复杂度。如果您的符号是以一种相当随机的方式插入的,那么这应该不是一个问题。如果它们是按顺序插入的,那么您将构建一个链表。(对于您的特定应用程序,它们不应该按任何类型的顺序排列,所以应该没问题。)如果有一个机会,符号将太有序,一个 红-黑树是一个更好的选择。
散列表提供 O (1)平均插入和查找复杂度,但这里也有一个警告。如果您的散列函数不好(我的意思是 真的不好) ,您可能会在这里建立一个链表。但是,任何合理的字符串散列函数都应该这样做,所以这个警告实际上只是为了确保您意识到它可能发生。您应该能够测试散列函数在预期的输入范围内没有多少冲突,这样就没问题了。另一个小缺点是,如果使用的是固定大小的哈希表。大多数哈希表实现在达到一定大小时会增长(更精确地说,是加载因子,详见 给你)。这是为了避免将一百万个符号插入到十个桶中时出现的问题。这只会导致10个链表,平均大小为100,000。
如果是这样,您可以考虑在这些其他结构中选择一个排序列表。在执行插入操作时,这种方法的性能会比其他方法差,因为在插入操作中,排序列表是 O (N) ,而对于链表或散列表,排序列表是 O (1) ,对于平衡二叉搜索树,排序列表是 O (log2N)。但是排序列表中的查找可能比其他任何结构都要快(我将在稍后解释这一点) ,因此您可能会占据上风。另外,如果一次执行所有插入(或者在所有插入完成之前不需要查找) ,那么可以简化对 O (1)的插入,并在最后进行一次快得多的排序。更重要的是,排序列表比其他任何结构使用更少的内存,但是这种情况发生的唯一可能的方式是您有许多小列表。如果您有一个或几个大列表,那么散列表的性能很可能优于排序列表。
为什么使用排序列表查找可能更快?很明显,它比链表快,后者的 O (N)查找时间。对于二叉树,只有当树保持完全平衡时,查找才保持 O (log2N)。保持树的平衡(例如,红-黑)增加了复杂性和插入时间。此外,对于链表和二进制树,每个元素都是一个单独分配的 1节点,这意味着您将不得不取消引用指针,并可能跳转到可能存在很大差异的内存地址,从而增加缓存丢失的几率。