二叉搜索树还是哈希表?

3 投票
3 回答
518 浏览
提问于 2025-04-16 17:15

我有一些很大的文本文件,需要对这些文件进行各种操作,主要是逐行验证。这些数据通常与销售或交易有关,因此在行与行之间往往会有很多重复的信息,比如客户名字。处理和操作这些数据已经成为一项常见的任务,所以我正在用C语言编写一个库,希望能把它做成一个Python模块。

在一次测试中,我发现130万个列值中,只有大约30万个是独一无二的。内存使用量是一个问题,因为我们的Python网页应用可能会同时处理多个大数据集的请求。

我第一次尝试是读取文件,把每个列值插入到一个二叉搜索树里。如果这个值之前没有出现过,就会分配内存来存储这个字符串;如果已经存在,就返回指向那个值的现有存储的指针。对于大约10万行的数据集,这个方法效果不错。但如果数据集更大,处理速度就会变得很慢,内存消耗也会飙升。我猜树中那些节点指针的开销并没有帮助,而且用strcmp进行二叉搜索也变得非常麻烦。

这种不理想的表现让我觉得应该考虑使用哈希表。不过,这又带来了另一个问题——我事先根本不知道会有多少记录。可能是10条,也可能是1000万条。我该如何在时间和空间之间找到一个合适的平衡,以避免哈希表一次又一次地调整大小呢?

在这种情况下,最合适的数据结构是什么呢?

感谢你的时间。

3 个回答

0

我希望能把一个用C语言写的库做成Python模块。

Python里面已经有非常高效、调校得很好的哈希表了。我强烈建议你先把你的库或模块在Python中做好。然后再检查一下速度。如果速度不够快,就分析一下性能,找出那些拖慢速度的地方,可能可以用Cython来解决。

设置代码:

shared_table = {}
string_sharer = shared_table.setdefault

压缩每一行输入数据:

for i, field in enumerate(fields):
    fields[i] = string_sharer(field, field)

当然,你在检查每一列的时候,可能会发现有些列压缩效果不好,应该排除在“压缩”之外。

1

哈希表的大小调整其实不是个大问题,除非你有要求希望每次插入的时间都一样。只要你每次扩展哈希表的大小是按固定比例增加,比如说每次增加50%,那么添加一个新元素的时间平均下来就是 O(1)。这意味着当你进行 n 次插入操作时(当 n 很大的时候),所花的时间和 n 是成正比的。不过,实际每次插入所需的时间可能会有很大差别(在实际操作中,有一次插入可能会非常慢,而其他的则会很快,但所有操作的平均时间还是很小的)。原因是,当你插入一个新元素,导致哈希表的大小从比如说1000000扩展到1500000时,这次插入会花费很多时间,但这之后你就可以进行500000次非常快速的插入,而不需要再调整大小。总之,我绝对推荐使用哈希表。

撰写回答