一、题目
说明在散列表内部,如何通过将所有未占用的槽连接成一个自由链表,来分配和存储元素所占的存储空间。假定一个槽可以存储一个标志、一个元素、一个或两个指针。所有的字典和自由链表操作均应具有O(1)的期望运行时间。该自由链表需要是双向链表吗?或者单链表就足够了?
二、思路整理(参考官方答案)
每个槽slot有一个布尔值flag属性,表明是否已占用;
未占用slot:一个双向链表把空闲slot都连接起来,每个free slot有两个指针;
已占用slot:包含一个元素element和两个指针(参考答案是使用一个指针,这里为了方便)(可能nil),分别指向上一个和下一个散列到这个slot的元素,也就是是指向另一个slot。(因为所有element都存储在slot中)
一个slot定义如下:
struct node(){
bool flag;//1为已占用,0未占用
int key;//未占用:没意义,-1;已占用:元素关键字
int prev;//未占用:上一个空槽;<span style="font-family: Arial, Helvetica, sans-serif;">已占用:上一个具有相同散列值的元素</span>
int next;//未占用:下一个空slot ;已占用:下一个具有相同散列值的元素
}
1、如果元素x散列到一个空slot,将这个空slot从Free List移除,把x放到这个slot里,next指针指向nil,然后维护FreeList指针;
2、如果元素x散列到一个非空slot槽位j,该slot已存储元素y,分两种情况:
a、hash(y)=j:FreeList分配一个新slot存储x,将其插入y与y.next元素之间,即新slot指向y.next,y的指针指向新slot;
b、hash(y)