【问题标题】:Java Doubly Linked list delete methodJava双向链表删除方法
【发布时间】:2020-12-24 12:33:13
【问题描述】:

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

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

我在这里寻求有关我的问题的提示或提示 (对不起我的英语不好)

【问题讨论】:

  • 您是否在输出中找不到项目?
  • 不确定这是否是唯一的问题,但在循环标头中,您将Strings 与== 进行比较。
  • 你的 catch 程序有一个空的 try 块。除非您真的知道自己在做什么,否则请不要这样做。至少添加 e.printStackTrace() 用于调试目的。
  • 这是学习使用调试器的好时机。

标签: java oop doubly-linked-list


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • op没有说双链表是循环的
    • 感谢您回答我的问题,我遵循了您的代码,它给了我一条错误消息,上面写着 'else if(!current.next) {' 错误:一元运算符的错误操作数类型节点'!'目前正在尝试修复
    • 我的小错误。你能用上面的修改代码再试一次吗?
    【解决方案3】:

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

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

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

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

    我会改写为:

    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 语句和标志来保护它。

    【讨论】:

      【解决方案4】:
      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;
            }
      }
      

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

      【讨论】:

        猜你喜欢
        • 2012-03-23
        • 1970-01-01
        • 2018-09-16
        • 1970-01-01
        • 2017-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多