简体   繁体   English

在跳过列表中搜索元素

[英]Searching for element in Skip List

I'm having some difficulty coding up a way to find an element in a Skip List. 我在编写一种在跳过列表中查找元素的方法时遇到了一些困难。

I'm trying to implement it so that, if we're searching for an element and that element doesn't exist in the List, then return the next largest value; 我正在尝试实现它,以便如果我们正在搜索一个元素并且List中不存在该元素,则返回下一个最大值; this would make it ideal for insertion. 这将使其非常适合插入。 However, if the element is located, then return that element. 然而,如果元件位置,然后返回该元素。

I use this for my remove(T key) method; 我将其用于我的remove(T key)方法; if we find the element, then remove it. 如果找到元素,则将其删除。 If it isn't in the list, throw new java.util.NoSuchElementException() . 如果不在列表中,则throw new java.util.NoSuchElementException()

While my current implementation works okay for insertion, I've come to find out that it doesn't work at finding an existing element--instead, it will get the next value. 虽然我当前的实现可以很好地插入,但是我发现它在查找现有元素上不起作用-相反,它将获得下一个值。 (It shouldn't technically work for insertion, but it does). (从技术上讲,它不应该用于插入,但是可以)。

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

Above, is what the Skip List looks like currently. 上方是“跳过列表”当前的外观。

Below, is the structure of the Skip List I'm making. 下面是我正在制作的跳过列表的结构。 The Left-Hand sentinels are nodes with data that is null; 左手哨兵是数据为空的节点。 we also have a phantom node acting as the head; 我们还有一个幻像节点作为头部; the phantom head helps us keep track of the current number of levels in the Skip List. 幻像头可以帮助我们跟踪“跳过列表”中的当前级别数。 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;
}

In its current state, if we try search(4) , the returned node will be 5 , even though 4 is in the list. 在当前状态下,如果我们尝试search(4) ,即使列表中有4 5 ,返回的节点也将是5

I'm seeing a number of problems here. 我在这里看到许多问题。

  1. Where are you actually returning the value? 您实际在哪里返回值? I see no return statement, though I presume you just left out a return node; 我没有看到return语句,尽管我认为您只是省略了return node; at the bottom. 在底部。

  2. You're never verifying that the final value is indeed what you're looking for. 您永远不会验证最终值确实是您想要的。 You need some way to indicate that a value wasn't found, I'm assuming? 我假设您需要某种方式来指示未找到值?

  3. You currently just decide that you found the node if you weren't able to go down. 当前,如果您无法断开连接,则只需确定已找到该节点。

I think you need to re-think the algorithm a bit. 我认为您需要重新考虑一下算法。 Try this code: 试试这个代码:

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;
}

Note the checking for a null condition in the inner while loop - this prevents you from calling getData() on a non-existent next node, which would result in a null pointer exception. 请注意在内部while循环中检查是否为空条件-这可防止您在不存在的下一个节点上调用getData() ,这将导致空指针异常。 Also note how you don't check for null values going down. 还要注意如何不检查空值是否下降。 This is because you only encounter it if it's not in the list, so the special case at the start will catch that null value the next time the loop executes. 这是因为只有当它不在列表中时才会遇到它,因此在特殊情况下,开始时,下一次执行循环时将捕获该空值。

You can also tweak how it checks if the values are equal. 您还可以调整它如何检查值是否相等。 I used .equals but you can change it to use the compare method, depending on how you check for equality. 我使用了.equals但是您可以更改它以使用compare方法,具体取决于您检查相等性的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM