Java双向链表删除方法

问题描述

我的问题是我的删除方法没有删除我想删除的节点并给我一个无限循环。

public void delete(String name){
      Node current = head;
      boolean checker = false;
         while(current != null && current.name != name && checker != true){
            try{
               if(current.name.equals(name)){
                  Node p = current.prevIoUs;
                  Node q = current.next;
/*The code can somehow get through only above this line,below here its not anymore*/
                  p.next = q;
                  q.prevIoUs = p;
                  System.out.println("Item successfully deleted.");
                  checker = true;
               }else if(!current.name.equals(name) && current == tail){
                  System.out.println("Item not found.");
               }
               current = current.next;
            } catch(NullPointerException e){}          
         }
   }

我是来寻求有关我的问题的提示提示 (抱歉我的英语不好)

解决方法

您正在检查是否已到达列表 current == tail 的末尾,但没有跳出。您可以在 break 中添加 else if 语句。

除此之外,您使用 == 来比较字符串。我不确定你为什么在那里添加它并且它可以被删除。此外,您必须(几乎总是)永远不要捕获 NullPointerException。

,

“无限循环”意味着您的循环条件不正确,您在每次迭代中都没有取得进展,或者您的数据存在循环。您同时使用 current == null 和 current == tail 来表示它是最后一个元素。选择一种方式。建议您重写循环条件以仅处理迭代,如果主体中有匹配项,则使用带中断的条件:

for(current = head; current; current = current.next) {
   if(current.name.equals(name)) {
     if(current == head)
        head = current.next
     else
        current.previous.next = current.next; 

     if(current == tail)
        tail = current.previous;
     else
        current.next.previous = current.previous;

     break;
   }
   // if tail.next is not initialized to null
   // if(current == tail) break;
}
,

我在这里看到了一个没有副作用的潜在无限循环。如果您的列表包含 node.name 设置为 null 的节点,则调用 current.name.equals(name) 会导致 NullPointerException。如果您位于列表的任一端,则 next 或 previous 指针将为空,这也会导致相同的异常。此异常被捕获并丢弃。请注意,这会阻止导致相同迭代发生的当前指针的前进。即使您没有采取任何其他操作,至少也要确保打印出异常。这将有助于调试。

您的 while 循环条件过于复杂。 while(current != null) 应该足够了:

使用 if(current.name.equals(name)) 消除了对 current.name != name 的需要。另外,不要使用 == 或 != 进行字符串比较。这是一个指针比较。大多数 equals 方法负责指针比较。

在此处使用中断或返回进行流控制并删除检查器布尔值。 tail.next 应始终指向 null 以表示列表的末尾。我看到有 checker 布尔值的唯一原因是 delete 是否应该删除所有匹配的节点,并且您想知道它是否至少发生过一次。从我在代码中看到的情况并非如此。

我会改写为:

public void delete(String name){
    Node current = head;
    while(current != null){
        try{
            if(current.name.equals(name)){
                ...
                return;
                // Do not advance current here. Refer to finally block below.
            }
        } catch(NullPointerException e){
            e.printStackTrace();
            return; // If function should stop on error.
        } finally {current = current.next;} // This prevents the repeat as it always happens.
    }
    System.out.println("Item not found.");
}

请注意,如果您使用“break”而不是“return”,则会出现“Item not found”。行将始终打印。你必须用一个 if 语句和一个标志来保护它。

,
public void delete(String name){
      Node current = head;
      while(current != null){
        if(current.name.equals(name)){
            if(current.prev != null){
             current.prev.next = current.next
            }
            if(current.next != null){
                current.next.prev = current.prev
            }
            System.out.println("Removed node")
            break;
        }
        current = current.next;
      }
}

如果节点不为空,您可以使用此逻辑删除与名称匹配的节点(给定名称始终存在)。