Java 为什么可以';是否删除链接列表中的引用?

Java 为什么可以';是否删除链接列表中的引用?,java,algorithm,data-structures,linked-list,Java,Algorithm,Data Structures,Linked List,问题:给定一个值,从链表中删除该值的所有实例。更多信息如下:JAVA 既然它是一个传递引用,它应该是更新的,不是吗 我试过: removeElements([1,2,6,3,4,5,6], 6) 但它没有移除任何东西。那么我做错了什么呢?有几个问题: 您希望循环直到节点为null而不是直到节点不为null(即,而(…!=null)) 您可能希望循环直到n为null,而不是直到n。next为null,否则您将跳过最后一个元素 您希望检查n.val==val而不是n.next.val==val,

问题:给定一个值,从链表中删除该值的所有实例。更多信息如下:JAVA

既然它是一个传递引用,它应该是更新的,不是吗

我试过:

removeElements([1,2,6,3,4,5,6], 6)

但它没有移除任何东西。那么我做错了什么呢?

有几个问题:

  • 您希望循环直到节点为null而不是直到节点不为null(即,
    而(…!=null)
  • 您可能希望循环直到
    n
    为null,而不是直到
    n。next
    为null,否则您将跳过最后一个元素
  • 您希望检查
    n.val==val
    而不是
    n.next.val==val
    ,否则将跳过第一个元素
  • 如果选中
    n
    ,则希望跟踪上一个节点,以防需要删除
    n
    ,即
    prev.next=n.next
  • 如果要删除第一个元素(头部),则需要更换头部,即返回第二个元素(可以通过检查
    prev==null
    来完成,这意味着
    n
    是当前头部)

正如Thomas在其第一点中提到的,您错误地编写了while循环。另外,因为您有一个单一的链表,所以需要跟踪上一个节点(Thomas也提到)


使用适当的测试用例来解决这些问题总是一个很好的实践。设计可能的测试用例,包括转角用例。然后遵循您的算法,看看它是否解决了测试用例的问题。编写代码并试运行,这将对代码和逻辑进行健全性检查

下面是这个问题必须编写测试用例的案例

  • 空列表
  • 具有一个元素且值等于要删除的值的列表
  • 具有一个元素且值不等于要删除的值的列表
  • 具有两个元素且第一个节点值等于要删除的值的列表
  • 包含两个元素且最后一个节点值等于要删除的值的列表
  • 包含三个元素且第一个节点值等于要删除的值的列表
  • 包含三个元素且第二个节点值等于要删除的值的列表
  • 包含三个元素且最后一个节点值等于要删除的值的列表
  • 下面是删除链表中具有给定值的节点的代码

    public ListNode removeElements(ListNode head, int val) {
            while(head != null && head.val == val){
                head = head.next;
            }
            if(head == null){
                return null;
            }
            ListNode node = head;
            while(node.next != null){
                if(node.next.val == val){
                    node.next = node.next.next;
                }else{
                    node = node.next;
                }
            }
            return head;
    }
    

    因为它应该是while(n.next!=null),所以您也不会检查head是否包含您的值。您缺少了很多这方面的检查语句。
    while(n.next==null){
    如果您将长度为1的列表传递给
    removeements
    ,并且如果列表较长,则什么也没有。对于前两行
    while(head!=null&&head.val==val){head=head.next;}
    完成此循环后,节点会减少很多,不是吗?假设我有
    1->2->3->1->null
    和所需的
    val=1
    ,然后在循环完成时
    head=null
    ?否,因为循环会检查head处的值是否等于所需值,然后仅在下一个节点停止时修改head。在您的在第一次循环后,r箱头将位于值为2的节点。
    public static ListNode removeElements(ListNode head, int val)
    {
        ListNode n = head;
        ListNode prev = null; //the previous node.
        while (n != null)
        {
            if (n.value == val)
            {
                //if prev is null it means that we have to delete the head
                //and therefore we need to advance the head
                if (prev == null)
                {
                    head = n.next;
                    prev = null;//remains at null because there's nothing before head
                    n = head;//new head, let's start from here
                } else
                {
                    prev.next = n.next; //let's skip the element to delete
                    n = n.next;//let's advance to the next node
                }
            } else
            {
                //nothing to delete, let's advance to the next node and make 
                //the current node the previous node in the next iteration
                prev = n;
                n = n.next;
            }
    
        }
        return head;
    }
    
    public ListNode removeElements(ListNode head, int val) {
            while(head != null && head.val == val){
                head = head.next;
            }
            if(head == null){
                return null;
            }
            ListNode node = head;
            while(node.next != null){
                if(node.next.val == val){
                    node.next = node.next.next;
                }else{
                    node = node.next;
                }
            }
            return head;
    }