浣熊今天读到《算法导论》的第十一章散列表,看到中文书的第135页(英文P224~225)时,被其中的一个知识点难住,想了许久终于有了答案,故撰此文与大家分享
在散列表发生碰撞问题的时候,其中一种解决方法叫“链接法”,具体的做法我就不介绍了。在这一部分的最后,书作者提出如果采用双向链表的话,则删除操作可以在O(1)时间内完成,这便是我疑问所在。其实我的不理解根源在于没有理解书中所说的元素x与关键值key的定义,按照作者所说,元素x中存放的是指向某个对象的指针,即x指向某一块内存区域;而key则是我们所关注的对象中的数据。有了这个概念后我的疑问就迎刃而解了:如果知道指向某个对象的指针,而且链表是双向的,那么我们就很容易找到指向这个对象的前一个对象和后一个对象的指针,那么删除该对象只需对其前一个对象和后一个对象的指针域进行相应修改即可。但是如果是单链表,我们知道指向某个对象的指针,仅仅能够获得指向该对象之后的对象的指针,无法获取指向它前一个对象的指针,这样就没有办法对该对象进行删除(无法对前一个对象的指针域赋值)。所以我们只有根据x的key值,找到对应的链表头,然后逐个查找,直到找到x,记录其前后对象指针,修改后即完成对象的删除工作。这样看来,如果是单链表情况下的删除操作,给key值和给x值是等价的,即都需要从表头遍历链表查找数据,而不像双链表那样可以直接对对象进行删除。