在Java中删除DoubleLinkedList中的对象时遇到麻烦

时间:2020-10-18 06:11:20

标签: java

我正在努力使用此remove(Object obj)方法。我尝试了许多不同的方法,这是我能得到的最接近的方法。被删除的项目是传入对象之前的项目:

public boolean remove(Object obj)
{
    if (!this.contains(obj))
        return false;

    //if we get to here, we know that the list contains obj somewhere
    //change the links and return true at the end.
    else if (head.data.equals(obj))    //is it at the front?
    {
        this.removeFirst();
        return true;
    }

    else    //not at front, so traverse the list
    {
        DLLNode<E> doomed = head;
        while (!doomed.data.equals(obj))
            doomed = doomed.next;

        //now that it is found, find the node in front of it
        DLLNode<E> inFront = head;
        while (inFront.next != doomed)
            inFront = inFront.next;

                    //
                    // HERE IS THE PROBLEM & MY EXPLANATION BEHIND IT
                    //
        // locate the prev locator of the following node of the obj and set it equal to the beginning (prev) of the node in front of the obj removed
        inFront.next.prev = inFront.prev;
        // locate the next locator of the preceding node of the obj and set it equal to the end (next) of the node in front of the obj removed
        inFront.prev.next = inFront.next;

        //also...if the one that was deleted was the tail, we must reset the tail
        if (doomed == tail)
            tail = inFront;
    }

    return true;   //found it; links have been changed

}

我测试中的当前输出是在与要传入的对象匹配的节点之前删除该节点。

谢谢。

编辑:为确保我能正确理解,我的inFront变量位于doomed变量的左边?至少这就是我编写代码时一直在想的方式。例如:

DDL:1-> 2-> 3

我要remove(2)

这意味着-

  • doomed = 2
  • inFront = 1

因此,inFront.next将是1的“下一个”节点?

编辑2:我现在明白我的想法是正确的。这样,我进行了调整,并能够通过更改以下内容来获得相同的输出:

inFront.next.prev = inFront.prev;
inFront.prev.next = inFront.next;

inFront.next = doomed.next.next.prev;

现在,从左到右读取DLL时将删除与该对象匹配的正确节点。但是,当从右向左读取DLL时,对象会再次出现在相同位置。

2 个答案:

答案 0 :(得分:1)

编辑:

是的,找到元素的代码是正确的。但是在删除部分,您曾以为“ inFront”是前一个节点,因此它删除了错误的节点。 现在要删除。在删除之前,您需要执行以下操作:

Befor deletion Image

现在,您必须将inFront.next设置为doomed.next

inFront.next=doomed.next;

您的列表现在看起来像这样:

enter image description here

下一步是将doomed.next.prev设置为inFront

doomed.next.prev=inFornt;

最终统计:

enter image description here 由于没有对注定对象的引用,因此垃圾收集器会将其从内存中删除。

答案 1 :(得分:0)

解决了!这是一个愚蠢的错误。我没有考虑其他情况。我了解到,如果没有向该社区提供所有信息,我不能指望任何人能够完全理解我的问题并提供帮助。这是在我身上。为了公开羞辱自己并说服他人将来提供必要的信息,我将解释问题和解决方案。

我最初的问题是被删除的节点是请求对象前面的那个节点。解决了这个问题:

inFront.next = doomed.next;
doomed.next.prev = inFront;

然后,我没有考虑这样一个事实,即在列表末尾删除的对象将需要特殊情况来避免诸如不删除或破坏与其他节点的连接之类的问题。这是通过创建一个if语句解决的:

if (doomed != tail) {
    inFront.next = doomed.next;
    doomed.next.prev = inFront;
} else {
    inFront.next = null;
}

谢谢!我一定会在以后更好地整理我的问题。