【问题标题】:Searching for element in Skip List在跳过列表中搜索元素
【发布时间】:2015-03-03 18:16:41
【问题描述】:

我在编写一种在跳过列表中查找元素的方法时遇到了一些困难。

我正在尝试实现它,如果我们正在搜索一个元素并且该元素在列表中不存在,则返回下一个最大值;这将使其成为插入的理想选择。 但是,如果元素 位于,则返回该元素。

我将它用于我的remove(T key) 方法;如果我们找到该元素,则将其删除。如果不在列表中,throw new java.util.NoSuchElementException()

虽然我当前的实现可以很好地用于插入,但我发现它在查找现有元素时不起作用——相反,它将获得下一个值。 (从技术上讲,它不应该适用于插入,但确实适用)。

********************** SkipList (size = 3) Level: 2 (null), , , (5) Level: 1 (null), (3), (4), (5) **********************

以上是跳过列表当前的样子。

下面是我正在制作的跳过列表的结构。左手标记是数据为空的节点;我们还有一个幻像节点作为头部;幻像头帮助我们跟踪跳过列表中的当前级别数。 Diagram of structure

private Node<T> search(T key) {
    Node<T> node = head;
    boolean found = false;

    while (!found) {
        while (compare(node.getNext().getData(), key) <= 0) {
            node = node.getNext();
        }
        if (node.getDown() != null) {
            node = node.getDown();
        } else {
            node = node.getNext();
            found = true;
        }
    }
    return node;
}

在其当前状态下,如果我们尝试search(4),则返回的节点将为5,即使4 在列表中。

【问题讨论】:

    标签: java list skip-lists


    【解决方案1】:

    我发现这里有很多问题。

    1. 您实际上在哪里返回值?我看不到 return 声明,但我认为您只是在底部遗漏了 return node;

    2. 您永远无法验证最终值是否确实是您正在寻找的。你需要一些方法来表明一个值没有找到,我假设?

    3. 如果您无法关闭,您目前只是决定找到该节点。

    我认为您需要重新考虑一下算法。试试这个代码:

    private Node<T> search(T key) {
        Node<T> node = head;
        boolean found = false;
    
        while (!found) {
            //special case to return a node containing null - indicates value not in list
            if (node == null) return new Node(null);
            //We found it!
            else if (node.getData().equals(key)) found = true;
            //Go to the next one over if it's not too high.
            else if (node.getNext() != null && compare(node.getNext().getData(), key) <= 0) node = node.getNext();
            //It was too high, so go down instead.
            else node = node.getDown();
        }
        return node;
    }
    

    注意在内部 while 循环中检查空条件 - 这可以防止您在不存在的下一个节点上调用 getData(),这将导致空指针异常。另请注意您如何不检查空值是否下降。这是因为只有当它不在列表中时才会遇到它,因此开始时的特殊情况将在下次循环执行时捕获该空值。

    您还可以调整检查值是否相等的方式。我使用了.equals,但您可以将其更改为使用compare 方法,具体取决于您检查相等性的方式。

    【讨论】:

    • 这仅适用于查找元素。如果节点在此列表中,我想找到它——但如果不是,则返回列表中的下一个最大值;这样,我可以轻松地在返回的节点之前插入新值。
    • 啊,我明白了。您是否测试过compare 方法被正确调用?如果您打算使用 &gt;= 而不是 &lt;=,我可以看出这是问题所在。
    • 方法如下:compare(T a, T b),然后我做a.compareTo(b)。我知道如果我们运行search(3),那么它会比较3.compareTo(5),它会正确返回-1;这就是为什么我不明白为什么它不起作用。
    • 我也不确定你的方法是否有效。如果我们search(3),那么我们最终会转到5,然后再转到5。这是不正确的。它应该沿着左侧列向下直到data &lt;= node.next.data。您的算法会立即转到第 2 层的第一个 5
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    相关资源
    最近更新 更多