Java 删除节点有问题

Java 删除节点有问题,java,algorithm,data-structures,Java,Algorithm,Data Structures,我的问题是关于一个需要delet节点的lintcode练习,但由于某种原因,我的简单程序无法工作 例如,输入(1->2->3->4->null,3)应该输出(1->2->4->null),我的想法是删除下一个节点并“复制”它的值来输入这个节点 /** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { *

我的问题是关于一个需要delet节点的lintcode练习,但由于某种原因,我的简单程序无法工作

例如,输入(1->2->3->4->null,3)应该输出(1->2->4->null),我的想法是删除下一个节点并“复制”它的值来输入这个节点

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param node: the node in the list should be deleted
     * @return: nothing
     */
    public void deleteNode(ListNode node) {
        // write your code here
        ListNode pnext;
        if (node != null) {
            if (node.next != null) {
                ListNode tempnode = node.next;
                if (node.next.next != null) {
                    pnext = node.next.next;
                }
                else {
                    pnext = null;
                }

                node.next = null; //delete next node
                node = tempnode; // give next node to THIS node
                node.next = pnext; // link next
            }
        }
        else node = null;
    }
}

我对赋予node值感到非常困惑,
node1=node2
甚至有效吗?我知道node.val可以。谁能简单地指导我一下吗?

你不必要地把事情复杂化了,事情并没有那么棘手。如我所见,您只是将
ListNode
作为参数,而不是要删除的
数据。此外,由于您在使用
if
而不是
的同时
for
,因此您永远不会迭代整个列表

您应该修改函数以获取
节点
数据
,并开始使用循环来迭代完整列表

以下是代码片段:

private void deleteNode(ListNode node, int data) {
    while(node != null && node.data != data) {
        node = node.next;
    }

    if(node != null) {
        System.out.println("Deleted Node With Data: " + node.data);
        node = node.next;
    }
}

你不必要地把事情复杂化了,事情并没有那么艰难。如我所见,您只是将
ListNode
作为参数,而不是要删除的
数据。此外,由于您在使用
if
而不是
的同时
for
,因此您永远不会迭代整个列表

您应该修改函数以获取
节点
数据
,并开始使用循环来迭代完整列表

以下是代码片段:

private void deleteNode(ListNode node, int data) {
    while(node != null && node.data != data) {
        node = node.next;
    }

    if(node != null) {
        System.out.println("Deleted Node With Data: " + node.data);
        node = node.next;
    }
}

你的帖子中没有包括实际发生的事情,也没有包括创建列表的部分,所以我只能假设你没有删除3个,而是删除了4个?或者它根本不删除任何内容

因此,您有一个应该删除节点的方法,并且要删除的节点作为参数给定。但由于列表仅以一种方式链接,因此无法确定其前面的节点(该节点包含对要删除的节点的引用)。实际上,delete方法应该像这样简单:

public void deleteNextNode(ListNode node) {
    if(node == null || node.next == null) return; //nothing to delete
    if(node.next.next == null){
        node.next = null;
        return;
    } else{
        node.next = node.next.next;
    }
}
虽然我没有测试它。只要不存储对节点的任何其他引用,这就足够了,否则需要在else部分显式调用next.null

编辑:我的函数删除您传递的节点后面的节点,但您需要一个函数删除您传递的节点。这里的问题是,前一个节点存储了对要删除的节点的引用,但您无法仅通过对要删除的节点的引用来确定该节点。因此,要么使用此函数并始终传递前一个节点,要么创建一个包装函数并遍历列表,始终保护前一个节点并使用该节点调用函数:

public ListNode deleteNode(ListNode start, ListNode deleteMe)
{
    ListNode prev = start;
    if(start == deleteMe) return start.next;
    while(prev.next != null) {
        if(prev.next == deleteMe)
            deleteNextNode(prev);
        prev = prev.next;
    }
    return start;
}
请注意,我让函数返回一个ListNode,它始终是列表的第一个节点(如果您决定删除第一个节点)。
我希望这会有所帮助

您的帖子中没有包括实际发生的事情,也没有包括创建列表的部分,因此我只能假设您没有删除3,而是删除了4?或者它根本不删除任何内容

因此,您有一个应该删除节点的方法,并且要删除的节点作为参数给定。但由于列表仅以一种方式链接,因此无法确定其前面的节点(该节点包含对要删除的节点的引用)。实际上,delete方法应该像这样简单:

public void deleteNextNode(ListNode node) {
    if(node == null || node.next == null) return; //nothing to delete
    if(node.next.next == null){
        node.next = null;
        return;
    } else{
        node.next = node.next.next;
    }
}
虽然我没有测试它。只要不存储对节点的任何其他引用,这就足够了,否则需要在else部分显式调用next.null

编辑:我的函数删除您传递的节点后面的节点,但您需要一个函数删除您传递的节点。这里的问题是,前一个节点存储了对要删除的节点的引用,但您无法仅通过对要删除的节点的引用来确定该节点。因此,要么使用此函数并始终传递前一个节点,要么创建一个包装函数并遍历列表,始终保护前一个节点并使用该节点调用函数:

public ListNode deleteNode(ListNode start, ListNode deleteMe)
{
    ListNode prev = start;
    if(start == deleteMe) return start.next;
    while(prev.next != null) {
        if(prev.next == deleteMe)
            deleteNextNode(prev);
        prev = prev.next;
    }
    return start;
}
请注意,我让函数返回一个ListNode,它始终是列表的第一个节点(如果您决定删除第一个节点)。 我希望这能有所帮助

我认为:

node = tempNode; // give next node to THIS node.
你的意思是:

node.val = tempNode.val; // give next node value to THIS node.
这样,下一个节点的值将复制到当前节点中。 接下来,您还需要执行以下操作:

node.next = tempNode.next;
这样,节点实际上就变成了tempNode。我想这是你的意图

我认为:

node = tempNode; // give next node to THIS node.
你的意思是:

node.val = tempNode.val; // give next node value to THIS node.
这样,下一个节点的值将复制到当前节点中。 接下来,您还需要执行以下操作:

node.next = tempNode.next;

这样,节点实际上就变成了tempNode。我想这是你的意图

嗯。。实际上我想删除3,所以我必须将前一个节点链接到4,这意味着我需要删除4,但将节点4复制到节点3,然后节点3被“删除”,因为它变成了节点4。链表不是这样工作的。您无需复制任何内容,只需将节点
2
的引用更改为指向节点
3
的下一个,即节点
4
,就这样!正如我在下面的回答中所说,你把问题复杂化了。只要试一下下面的代码就行了。简单的人..非常感谢,但这不是它的工作原理,我尝试了你的想法,但失败了。。也许你可以查看这个链接:正如user2004685已经指出的,你不需要复制任何东西。如果要删除Node3,只需更改Node4旁边的Node2.0的引用即可。如果您现在运行该列表,则有Node1、Node2、Node4(因为您更改了Node2.next到Node4的引用!)。这就是它的工作原理。如果您想传递应该被删除的节点作为引用,那么您应该像user2004685的解决方案那样在列表中迭代,您不需要传递数据,只需迭代,直到遇到