面向对象的java双链表删除方法

inn6fuwd  于 2021-06-29  发布在  Java
关注(0)|答案(4)|浏览(452)

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

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){}          
         }
   }

我来这里是想就我的问题寻求一些提示或建议(对不起,我的英语不好)

pvabu6sv

pvabu6sv1#

您正在检查是否已到达列表的末尾 current == tail 但不是从中解脱出来。您可以添加 break 你内心的陈述 else if .
除此之外,您正在使用 == 比较字符串。我不知道你为什么在那里加了这个,然后就可以删除了。而且,您必须(几乎总是)永远不要捕获nullpointerexception。

wwtsj6pe

wwtsj6pe2#

“无限循环”意味着你的循环条件是不正确的,你没有在每次迭代中取得进展,或者你的数据有一个循环。使用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;
}
8wtpewkr

8wtpewkr3#

我看到一个没有副作用的潜在无限循环。如果列表中包含node.name设置为null的节点,则 current.name.equals(name) 导致nullpointerexception。如果您位于列表的任意一端,则下一个或上一个指针将为null,这也将导致相同的异常。捕获并丢弃此异常。请注意,这样可以防止当前指针前进,从而导致相同的迭代发生。至少要确保打印出异常,即使您没有执行任何其他操作。这将有助于调试。
while循环条件过于复杂。 while(current != null) 鉴于:
使用 if(current.name.equals(name)) 不再需要current.name!=姓名。另外,不要使用==或!=用于字符串比较。它是指针比较。大多数equals方法负责指针比较。
在此处为流控制使用break或return并删除checker boolean。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语句和旗帜来保护它。

5kgi1eie

5kgi1eie4#

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;
      }
}

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

相关问题