采用separate chaining解决冲突的hash table扩容究竟指什么?为何需要扩容?
为什么拉链法哈希表需要扩容?
咱们先从拉链法哈希表的工作逻辑说起:哈希表是用一个数组当「桶」,每个桶挂一条链表。添加元素时,先通过哈希函数算出它该进哪个桶,再挂到对应链表上。
你说的「不扩容也能正常工作」没错,但随着元素越来越多,问题会慢慢暴露:
- 桶的数量固定的话,每个桶上的链表会越来越长。比如一开始10个桶,加10个元素,每个桶大概1个节点;要是加到1000个元素,每个桶平均就有100个节点。
- 这时候你查、插、删元素,都得遍历长长的链表,速度会越来越慢。
再说说时间复杂度:哈希表的核心优势就是理想情况下查、插、删都是O(1)常数时间——但这个前提是每个桶的链表足够短。如果链表太长,这些操作的时间复杂度就会退化成O(k)(k是链表长度),和直接用链表存数据没啥区别,完全浪费了哈希表的设计初衷。
扩容就是解决这个问题的:
- 把桶的数量增加(通常是翻倍),然后把原来所有元素重新计算哈希值,分到新的桶里。
- 这样每个桶的链表长度会立刻缩短,比如10个桶变20个,1000个元素平均每个桶就只有50个节点,再扩容到40个,平均25个——始终把链表长度控制在很小的范围内,让操作效率回到接近O(1)的水平。
补充个细节:一般不会随便扩容,会看「负载因子」(元素总数 ÷ 桶的数量),比如负载因子超过0.7或者1的时候才触发扩容。这样既能保证操作效率,又不会因为频繁扩容浪费时间和空间。
内容的提问来源于stack exchange,提问作者ARandomLearner
相关产品推荐
相关产品推荐

