【问题标题】:Java LinkedList removing the last nodeJava LinkedList 删除最后一个节点
【发布时间】:2014-11-16 03:25:48
【问题描述】:

我有一个 Java 类,它由一个节点列表 WordNode 组成,它具有类 Word 的属性和一个名为 next 的 WordNode 对象,用作对下一个节点的引用,如下所示:

class WordNode
{
    Word word;
    WordNode next;

    WordNode(Word w)
    {
        word = w;
        next = null;
    }

    Word getWord()
    {
        return word;
    }
}

Word 类有一个名为name 的字符串:

class Word 
{
    String name;

    Word(String n)
    {
            this.name = n;
    }

    public String getName()
    {
            return name;    
    }

    public void setName(String n)
    {
        name = n;
    }
}

我有一个类,它是一个自定义的 LinkedList,我必须通过指定单词名称来添加和删除单词。我可以毫无问题地添加,但是当我想删除时,我遇到了一些问题。删除方法如下:

boolean remove(Word w)
{
    WordNode wm = new WordNode(w);

    if (list == null) return false; //can't delete on an empty list
    else
    {
        WordNode aux = list;

        while(aux != null)
        {
            if (wm.word.getName().compareTo(aux.word.getName()) == 0 ) //if the word to delete is found
            { 
                if (aux.next == null) //to erase the last element
                {
                    aux = null;       
                }
                else
                {
                    aux.word.setName(aux.next.word.getName()); //set current node's name to equal next node's

                    WordNode temp = aux.next.next;
                    aux.next = null; //to erase current node
                    aux.next = temp; //re-refer
                }                        
                return true;
            }
            else aux = aux.next;
        }

        return false; //reachable if word is not found
    }
}

list 应该是包含所有节点的 LinkedList。 aux 是一个辅助列表,它将循环通过 list 以避免取消链接。所以,如果我选择删除一个 WordNode,我会比较名称。节点在任意位置,除了最后一个节点:

if (aux.next == null) //to erase the last element
{
    aux = null;       
}

我希望使该节点为空以标记列表的新结尾,但它不会被删除。我可以改变什么来删除最后一个元素?感谢您提前提供任何帮助/建议

【问题讨论】:

  • aux = null 只是将您对对象 aux 的引用设置为 null。最好的方法就是 aux.prev.next = null
  • 我没有“prev”字段。但这不就是和aux = null一样吗?
  • if (aux.next == null) 只是告诉您您的辅助是列表中的最后一个节点。将最后一个元素的引用设置为 null 不会影响前一个节点,因为它的下一个节点直到引用您认为已删除的元素。这就是为什么你需要跟踪你之前的节点。

标签: java linked-list


【解决方案1】:

您必须清除 WordNode 的“下一个”指针。由于您没有“上一个”指针,因此您必须手动跟踪上一个 WordNode。

boolean remove(Word w)
{
    WordNode wm = new WordNode(w);

    if (list == null) return false; //can't delete on an empty list
    else
    {
        WordNode aux = list;
        WordNode prev = aux;

        while(aux != null)
        {
            if (wm.word.getName().compareTo(aux.word.getName()) == 0 ) //if the word to delete is found
            { 
                if (aux.next == null) //to erase the last element
                {
                    prev.next = null;
                    // Takes care of the case of a one-item list
                    aux = null;
                }
                else
                {
                    aux.word.setName(aux.next.word.getName()); //set current node's name to equal next node's

                    WordNode temp = aux.next.next;
                    aux.next = null; //to erase current node
                    aux.next = temp; //re-refer
                }                        
                return true;
            }
            else {
                prev = aux;
                aux = aux.next;
        }

        return false; //reachable if word is not found
    }
}

【讨论】:

  • 这成功了!但不是当列表中只有一个元素时。所以我在if (aux.next == null) 之前添加了if (prev == aux) list = null; 我测试了它并没有发现任何错误,但是你认为我错过了什么吗?无论如何,非常感谢,其余的代码都可以工作!
  • 我建议以正确的方式执行此操作,即添加一个“头”节点。如果您所说的列表只是第一个节点,并且您将其设置为 null,那么您的列表就消失了。您永远无法向列表中插入更多节点。您可以破解您的列表以检查if (list == null) { list = newNode },然后再插入新节点以使您的列表再次运行(如果它是null),但问题是它将成为一个新列表和所有以前的列表对它的引用仍然会保留null,而不是反映插入新节点的变化。
  • 啊,我的错。 aux 是 list 的副本,因此将其设置为 null 对实际的 list 对象没有影响。我认为现在我们保留了以前的节点,我们可以稍微简化删除。 prev.next = aux.next 应该可以完成这项工作。另外,就像马塞尔夫说的,我会加一个“头”。任何体面的列表实现都应该有。
  • 是的,所以当只有一个元素时,我将列表设为 null,因为 add 方法的第一个条件说,if(list == null) list = temp;temp 是一个带有单词的临时 WordNode加上。该程序现在可以运行,但我会尝试更改我的代码以包含一个头部
【解决方案2】:

添加一个head 节点。 然后在检查最后一个节点时,您将拥有:

if (aux.next == null) //to erase the last element
{
   aux.head.next = null;
}

【讨论】:

  • 那么,head 是否应该始终为 aux,因为它指的是第一个节点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
相关资源
最近更新 更多