无法删除链表中的最后一个节点

Posted

技术标签:

【中文标题】无法删除链表中的最后一个节点【英文标题】:Unable to delete last node in linked list 【发布时间】:2016-11-06 17:53:03 【问题描述】:

我试图从我的单链表中删除最后一个节点。但我仍然无法在代码中解决这个错误。我的 deleteFromEnd 方法没有删除最后一个节点。调用 delete 方法后,它仍然显示我要删除的节点。列表的其余部分被删除,但最后一个节点本身没有被删除。你能告诉我我错过了什么,或者错误在哪里吗?

链表:

package lab5;

public class LinkedList 

    public static void main(String argsp[]) 
        List ob = new List();

        ob.addAtStart("y", 6);
        ob.addAtStart("w", 4);
        ob.addAtStart("z", 3);

        ob.addAtEnd("a", 3);
        ob.addAtEnd("b", 4);
        ob.addAtEnd("c", 5);

        /*
         * ob.display(); System.out.println("Deleted first one");
         * ob.deleteFromStart();
         */
        ob.display();
        System.out.println("Deleted End one");
        ob.deleteFromEnd();
        ob.display();
    

列表:

package lab5;

public class List 

    Node head;

    public List() 
        head = null;
    

    public List(Node e) 
        head = e;
    

    Node oldfirst = null;
    Node lasthead = null;

    public void addAtStart(String name, int age) 
        Node newObject = new Node(name, age);
        newObject.next = head;

        if (oldfirst == null) 
            oldfirst = newObject;
        
        head = newObject;
        lasthead = head;

    

    public void display() 
        Node store = head;
        while (store != null) 
            store.display();
            store = store.next;
            System.out.println();
        
    

    public void addAtEnd(String name, int age) 
        Node atEndValue = new Node(name, age);
        oldfirst.next = atEndValue;
        oldfirst = atEndValue;
    

    public void deleteFromStart() 
        if (head.next != null) 
            head = head.next;
        
    

    public void deleteFromEnd() 
        Node start = head;
        Node prev = null;
        while (head != null) 
            prev = head;
            head = head.next;
        
        prev.next = null;
        head = prev;
    

    public Node search(String name) 
        return head;
    

    public boolean isEmpty() 
        return head == null;
    

    public int size() 
        return (head.toString()).length();
    

节点:

package lab5;

public class Node 

    String name;
    int age;
    Node next;

    public Node() 
        name = "Abc";
        age = 10;
        next = null;
    

    public Node(String name, int age) 
        this.name = name;
        this.age = age;
        next = null;
    

    public void display() 
        System.out.println("Name: " + name + " Age: " + age);
    

【问题讨论】:

@n***s 现在我问了新问题。 head = head.next; 的意义何在? 您正在使用 head 而不是使用本地变量 start 进行遍历。 【参考方案1】:

您正在修改错误的列表头指针。以下方法对我有用。

   public void deleteFromEnd() 
        Node start = head;
        Node prev = null;

        if(start == null || start.next == null)
        
            head = null;
            return;
        
        while (start.next != null) 
            prev = start;
            start = start.next;
        
        prev.next = null;
    

在稍微分析了您的代码之后,我发现了其他一些问题。您需要更新 addAtStartaddAtEnd 方法。

Node lasthead = null;

public void addAtStart(String name, int age) 
    Node newObject = new Node(name, age);
    newObject.next = head;
    if(head == null)
        lasthead = newObject;
    else if(head.next == null)
        lasthead = head;

    head = newObject;




public void addAtEnd(String name, int age) 
    Node atEndValue = new Node(name, age);
    lasthead.next = atEndValue;
    lasthead = atEndValue;

原因是,假设我从列表末尾删除一个节点。我无法在列表末尾添加元素。

【讨论】:

谢谢!哇!谢啦。你想给我评论一下我的代码在一条评论中有多少好坏我知道现在不是正确的时间但是请。 @BadarShahzadKhan 你可以在这里发布一个新问题codereview.stackexchange.com @iNan 注意:此代码在某些极端情况下存在问题,即列表中只有一个元素等。 @VahanSimonyan 是的!你说的对。检查代码后,我也发现了其他一些问题。【参考方案2】:

当您从单链表的末尾删除时,您必须执行以下操作:

    遍历列表,并创建一个变量来引用列表的倒数第二个元素。

    设置倒数第二个节点之后的节点为空

在遍历您的链表时,您永远不应该更改head 的值,因为这实际上会删除整个链表。由于您已经覆盖了 head 变量,因此您无法回到起点。相反,使用初始化为 head 的临时变量进行迭代。

最后,请记住考虑列表只有 1 个元素或已经为空的边缘情况:

public void deleteFromEnd() 
    Node current = head;
    Node previous = null;

    while (current != null && current.next != null) 
        previous = current;
        current = current.next;
    

    if (current == head) 
        head = null;
    

    if (previous != null) 
        previous.next = null;
    

【讨论】:

谢谢@n***s【参考方案3】:

不要改变链表的头部,否则你会丢失链表。 尝试对您的功能进行以下修改:

public void deleteFromEnd() 
        Node start = head;
        Node prev = null;
        if(start == null)
           return;
        
        if (start.next == null)
           head = null;
           return;
        
        while (start.next != null) 
            prev = start;
            start = start.next;
        
        prev.next = null;
    

【讨论】:

以上是关于无法删除链表中的最后一个节点的主要内容,如果未能解决你的问题,请参考以下文章

题目地址(237. 删除链表中的节点)

算法系列——删除链表中的节点

算法系列——删除链表中的节点

算法系列——删除链表中的节点

算法系列——删除链表中的节点

从链接列表中删除节点无法正常工作