提问者:小点点

“get”方法是否应该在线性探测中失败,如果两者之间存在空值。如果不是,我如何实现get方法?


所以我使用线性探测从头开始构建一个哈希表,Java以下方法:put(int key,String value),get(int key),delete(int key)和size()。所以我成功实现了这些方法,但我有一个理论问题。比如说,我做了以下事情:

    var map = new HashMap(5);
    map.put(1, "a");
    map.put(3, "b");
    map.put(4, "c");
    map.put(8, "d");
    map.put(13, "e");
    map.remove(8);
    System.out.println(map);
    System.out.println(map.get(13));

我的put方法工作正常,并根据线性探测算法放置键值对。现在我的输出是:

[null,1=a,13=e,3=b,4=c]null

所以我的问题是,如果我的'get'方法在理论上失败(因为线性探测)获得键值对13=e,因为在索引0处有一个null。此外,如果我不使用删除,我将成功获得13=e对。


共1个答案

匿名用户

你的问题非常合理,是众所周知的线性探测问题之一。

问题是,如果您的地图中的一个项目被删除,那么当您尝试搜索一个值时,在搜索过程中您必须通过删除的项目,您将无法找到它。

如果您知道其中的某些值可能为空(已删除的项目),您也可以以不同的方式询问,搜索值的正确方法是什么。

一种解决方案是搜索,直到你浏览了整个地图,如果没有找到,返回null。但这是一个非常糟糕的解决方案,因为每次你对地图中不存在的值使用get(或包含)方法时,你都必须浏览整个地图(复杂度为O(n)),这是不可接受的,因为HashMaps应该以至少平均恒定的复杂度(*O(1))来实现这些方法。

所以有多种解决方案,你可以研究和阅读它们。我会给你一个我知道的解决方案:

在您的HashMap中,保存另一个数组,该数组将在每个索引处包含将值放入映射所需的最大步骤(或跳转),该索引是您首先到达的。每次您在映射中放入新值时(使用put方法),您的方法都会记住您跳转到的第一个索引,然后如果您必须经历的总跳转大于帮助数组中此索引处的最大步骤,则更新它。

现在,在您的get()和包含()方法中,当您执行第一步时,您会从帮助数组中读取允许的最大步数,然后您只需跳转此步数,直到您可以确定您的值不存在。这而不是在您到达空值键时停止。