如果我们使用链表数组来实现哈希表,那么“add”可以以一种不需要遍历的方式来实现。这是对还是错?

Posted

技术标签:

【中文标题】如果我们使用链表数组来实现哈希表,那么“add”可以以一种不需要遍历的方式来实现。这是对还是错?【英文标题】:If we use an array of linked list to implement hash table, "add" could be implemented in a way that no traversing is needed. Is this true or false? 【发布时间】:2015-04-30 18:34:09 【问题描述】:

如果我们使用链表数组来实现哈希表,“add”可以以一种不需要遍历的方式实现。这是对还是错?我很困惑它是哪一个,因为我读了这本书,我就是无法安静地理解这个问题。如果您还可以发布一个简短的说明,为什么答案是 T 或 F,这样我就可以大致了解这将是很好的。

【问题讨论】:

【参考方案1】:

我相信答案是正确的。

这个问题基本上可以翻译成这样:

当发生碰撞时,是否需要在链表末尾添加新值,从而在过程中遍历整个链表?

建议的实现是一个链表数组。链表仅用于处理冲突,这意味着它们包含的节点不需要按任何特定顺序排列。

当发生碰撞时,您只需创建一个新节点并将其设置为链表的头部。将节点添加到链表很简单,不需要遍历完整的链表。

附带说明:查找将要求您遍历链表。

视觉示例

假设存储动物的大小为 3 的哈希表。它目前包含“熊”、“狮子”和“鹰”:

+---+
| 0 | -> 0
+---+
| 1 | -> bear -> lion -> 0
+---+
| 2 | -> eagle -> 0
+---+

我们尝试添加“狐狸”的图像,哈希函数返回 1。索引 1 处的表已经有两个动物的列表:碰撞!

我们不会将 'fox' 附加到该列表的末尾,从而遍历整个列表,而是简单地将 'fox' 设置为列表的新头部:

+---+
| 0 | -> 0
+---+
| 1 | -> fox -> bear -> lion -> 0
+---+
| 2 | -> eagle -> 0
+---+

代码示例

template <class KeyType, class ValueType, int Size>
class HashTable 

    template <class ValueType>
    struct LinkedList 
        ValueType value;
        LinkedList* next;
    

    int hash(const Key& key) 
        // some hash algorithm
    

    LinkedList* table[Size]; // the array that stores pointers to LinkedLists

public:
    void add(KeyType key, ValueType value) 
        int index = hash(key);
        LinkedList new_entry = new LinkedList();
        new_entry.value = value;
        // The next line of code has two possible outcomes:
        // 1. table[index] contains a nullpointer, it is thus empty and new_entry.next will be set to null.
        // 2. table[index] contains a pointer to a LinkedList, new_entry.next will then also point to that LinkedList.
        new_entry.next = table[index];
        table[index] = new_entry;
    
;

【讨论】:

以上是关于如果我们使用链表数组来实现哈希表,那么“add”可以以一种不需要遍历的方式来实现。这是对还是错?的主要内容,如果未能解决你的问题,请参考以下文章

环形链表(哈希表链表)寻找两个正序数组的中位数(数组二分查找)二进制求和(位运算数学)

在 C 中寻找数组(与链表)哈希表实现

HashMap的数据结构

数组链表与哈希

环形链表

hash表原理