从链表LUT中删除节点?

时间:2012-05-15 20:56:53

标签: java memory-management linked-list

我们正在尝试编写一种方法,用于从LUT的链表实现中删除具有特定键的节点。

我写的代码摘要:

public void delete (String k) {

    Node currNode = listHead;
    Node prevNode = listHead;

    Key key = new Key (k);

    while (!currNode.key.equals(k) && currNode != null){
        prevNode = currNode;
        currNode = currNode.next;
    }

    if (currNode == listHead) {
      listHead = listHead.next;
    } else {
      prevNode.next = currNode.next;
    }
}

我的朋友基本上写了相同的东西,但没有使用前一个节点指针,而是写作他的最后一行:

currNode = currNode.next //detach point, override

这些都是等价的吗?我认为我对它的Java内存管理感到困惑 如果您已经在其他地方创建了listHead节点,那么就写下:

Node currNode = listHead;

currNode仅存储对存储listHead的内存位置的引用,对吧?所以在你执行currNode = currNode.next的while循环中,你正在做的是进入currNode中引用的内存位置,然后查看下一个变量并将引用存储在{{1}中。 1}?所以基本上更新currNode所指向的位置。这意味着我朋友的代码错了,对吧?由于他的代码同样意味着:“使用currNode”的内存位置更新currNode中当前的引用。

有人会介意帮我除雾吗?

3 个答案:

答案 0 :(得分:3)

您的朋友不可能是正确的,因为必须更改.next的{​​{1}}字段才能从列表中删除Node

我想你知道,要从列表中删除节点Node,您需要设置节点N的{​​{1}}字段以引用节点.next。你朋友的方法不可能这样做,因为它没有改变任何节点的N-1字段。

至于内存,一旦N+1的{​​{1}}字段引用.next,则列表不再保留N-1。它是否有资格进行垃圾收集取决于程序中是否有其他内容引用它。但是这份清单现在已经洗掉了。

答案 1 :(得分:2)

您的查询已经得到了正确的答案,但您的代码中有一些错误不适合评论。

<强> NullPointerException

您的while循环条件是向后的。它应该是

while (currNode != null && !currNode.key.equals(k)) { ... }

当您到达列表末尾或列表中没有要开始的节点时,请避免使用NullPointerException

未找到值

该方法不处理列表中不包含k的情况。您需要在while循环后检查currNode null

if (currNode != null) {
    if (currNode == listHead)
        listHead = listHead.next;
    else
        prevNode.next = currNode.next;
}

答案 2 :(得分:1)

您的分析是正确的 - 您朋友的代码实际上不会从列表中删除该节点。

我认为使用调试器逐步执行代码可能有助于消除迷雾。如果您还没有使用集成开发环境(IDE),我建议使用IntelliJ IDEA,Eclipse或Netbeans - 所有这些都包含调试器。