当前位置: 首页 > 知识库问答 >
问题:

双链表删除第一次出现法

裘光启
2023-03-14

有人能帮我为这个双链接列表写一个RemoveFirstOccurse方法吗?

它删除目标数据第一次出现的节点。搜索从头部开始。如果目标数据不在列表中,那么列表保持不变。最后一个节点的下一个字段值为null。没有尾部引用。

public class DoublyLinkedList {

    protected Node head; // Note there is no tail reference.
    public void addToFront(String data) {
        head = new Node(data, head, null);
        if(head.next != null) {
            head.next.previous = head;
        }

    public void removeFirstOccurrence(String data) { 
    }

    protected class Node {
        protected String data;
        protected Node next;
        protected Node previous;
        private Node(String data, Node next, Node previous) {
            this.data = data;
            this.next = next;
            this.previous = previous;
        }
        private Node(String data) {
            this(data, null, null);
        }
    } // end of Node class 
} // end of DoublyLinkedList class

到目前为止,我写了这样的东西,但是当删除列表中没有的字符串时,我得到了一个空指针异常。我已经标记了NPE发生的地方。如果你能帮助找出原因,或者如果你有一个完全不同的方法来工作,那也没关系,请告诉我,谢谢!

public void removeFirstOccurance(String data) {
    if (data.equals(null)) {
        throw new java.lang.IllegalArgumentException("Data is null");
    }
    if (head == null) {
        throw new java.util.NoSuchElementException("List is empty");
    }

    Node current = head;
    if (current.data.equals(data)) {
        head = current.next;
    } else {
        boolean found = false; //keeps track if we found the element
        while (current != null && !found) {
            if (current.next.previous == null) { //NPE here
                current.next.previous = current;
            }
            current = current.next;
            if (current.data.equals(data)) {
                found = true;
                if (current.next == null) {
                    current.previous.next = null;
                } else {
                    current.previous.next = current.next;
                }
            }
        }
    }
}

共有3个答案

越狐若
2023-03-14

在访问循环中的current.next值之前,您没有测试它。因此,当到达列表的末尾时,会发生异常。

while (current != null && !found) { // testing current
    if (current.next.previous == null) { // accessing current.next + testing current.next.previous
        current.next.previous = current;
    }
    // your loop
}

注意:这看起来像是工作任务,所以我不会发布代码。

夔高寒
2023-03-14

这就是我帮助你找到bug的理由。计算current时发生空指针异常。下一个以前的。上一行确保当前!=空。因此,很可能是当前的。接下来是空值。测试这一点的一个简单方法是添加assert current。下一个!=在使用该值之前,为空。如果这个理论是正确的,那么断言异常将在此时抛出。然后,你可以开始检查你的其他代码,找出为什么current。next此时可能为空。

作为编程技巧,我建议您使用大量的assert语句。从长远来看,它们会帮你省去很多痛苦。对于阅读代码的其他人来说,它们也是一个很好的提示,告诉他们您假设的条件在每一点上都是正确的。

栾弘新
2023-03-14

只是一些提示,因为我甚至没有在这台机器上安装Java来检查代码。

我建议你把注意力集中在你必须做的事情上:找到第一件事。然后,一旦找到它:更新前面和后面节点的指针。

在我看来,你似乎忘记更新当前的。当前的上一个指针。下一步检查数据是否位于第一个节点时。这样就不会真正删除节点。。

所以,我的方法是有这样的东西

while(!current.data.equals(data) && current.next != null){
    current = current.next; // looking through the list
}

然后,仔细检查您是否还没有到达列表的末尾,更新指针,以便

current.previous.next = current.next;
current.next.previous = current.previous;

还请注意,如果只是为了复制一个值,您不需要将null视为特殊的东西。我的意思是在最后一个if中:

if (current.data.equals(data)) {
                found = true;
                if (current.next == null) {
                    current.previous.next = null;
                } else {
                    current.previous.next = current.next;
                }
            }

您可以简单地将指定为当前。以前的下一个=当前。其次

希望这有帮助。

 类似资料:
  • 以下代码删除双链接列表中的第一个节点。 如果列表只包含1个元素,我们将last的引用设置为null。我的问题是,我们为什么不将first的引用设置为null?这会有什么不同吗?

  • 我正在做一个双链表的实现。我希望链表有一定的长度限制。当列表变长时,删除最后一个节点。我这里有些问题。我想定义尾巴,这样我就不必寻找终点。下面是我正在研究的实现,它将允许长度为4,然后开始删除最后一个节点。 它似乎在删除最后一个节点,但之后会打印一些奇怪的符号。我猜这是我如何释放的问题,但我想不出来。注意:此代码中的一些代码取自https://gist.github.com/mycodeschoo

  • 我有一个头和lastNode的参考。嗨我有个问题。当我删除双向链表中的最后一个节点时,我必须将该节点的前一个引用设置为空,或者我可以离开它。我在删除lastNode时做了这样的事情。 当我使用toString方法时,它会按预期打印。只是想知道是否有必要将旧的last node prev设置为null。或者垃圾收集器只是删除它,因为没有对它的引用,即使旧节点仍然有对链接列表中某个节点的引用

  • 每次我运行我的双链接列表时,除了从列表后面删除外,所有方法都有效。我有一张4,3,9的单子。我从前面拆下(这拿走了4个)。然后,我调用了这个方法,它应该只删除9。相反,当我调用DL列表时,它返回null(这也删除了3)。请帮忙。 下面是代码的其余部分(它扩展了一个接口;生成的代码对于这个问题不是必需的,所以我们没有填写它。也就是说,节点后面的内容无关紧要)正确的代码:

  • 这是我的remove函数,用于删除具有元素的节点。我得到了一个seg错误,我很确定这是因为temp->prev是前面的哨兵,所以从技术上来说,它不在双链表中。如果这是正确的,我实际上如何防止这种情况?如有任何帮助,不胜感激。 编辑:刚刚更新了代码,但仍然出现了Seg错误

  • 我有一个表,需要删除整个行,其中ID发生第二次和以后的时间,但留下第一次出现suCustoriID顺便说一下。M表的ID是主键,CustometID是重复的。因此,我需要删除所有重复的自定义ID行。 上面的代码将删除所有id,包括每个id的第一次出现,但我需要保留它们的第一次出现。请告知。