简体   繁体   中英

Unable to delete last node in linked list

I trying to delete the last node from my singly-linked list. But I am still unable to resolve this error in code. My deleteFromEnd method is not removing the last node. After calling the delete method, it's still showing the node that I want to delete. The rest of the list is deleted, but the last node itself is not removed. Can you tell me what I am missing, or where the error is?

LinkedList:

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

List:

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

Node:

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

You are modifying head pointer of list which is wrong. Following method worked for me.

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

After analysing your code for little more, I found few other issues. You would need to update addAtStart and addAtEnd methods.

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

The reason being, suppose if I delete a single node from the end of the list. I would not be able to add an element to the end of the list.

When you're deleting from the end of a singly-linked list you have to do things:

  1. Traverse the list, and create a variable to refer to the second-to-last element of your list.

  2. Set the node after the second-to-last node to be null

You should never change the value of head while traversing your linked list, because that effectively deletes the entire list. You have no way of finding your way back to the beginning since you've overwritten your head variable. Instead, iterate using a temporary variable which is initialized as head .

Finally, remember to consider the edge-cases where the list only has 1 element, or is already empty:

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

Do not change head of Linked List, otherwise you will loose the list. Try following modification of your function:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM