reticentroot
reticentroot

Reputation: 3682

Why isn't the head node of my linked list being deleted?

Okay, so i'm playing with linked list in Java. I'm trying to understand why my deleteNode method doesn't delete the head node. It works for other nodes.

Here's the method

Node deleteNode(Node head, int d){
        Node n = head;
        if(n.data == d){
            return head.next;
        }

        while(n.next != null){
            if(n.next.data == d){
                n.next = n.next.next;
                return head;
            }
            n = n.next;
        }
        return head;
    }

Sample input:

Node ll = new Node(1);
ll.appendToTail(2);
ll.appendToTail(3);

When I call my method

ll.deleteNode(ll, 2);

and then print the current Nodes, I get the correct output of 1->3, however when I use the method to delete the initial node or the head

ll.deleteNode(ll, 1);

I get the output 1->2->3, but I expect 2->3, where 2 becomes the new head. Below is the entire implementation just incase

public class Node {

    Node next = null;
    int data;

    public Node(int d){
        data = d;
    }

    void appendToTail(int d){

        Node end = new Node(d); //Item to append to the end
        Node n = this; //To access Class object next

        while(n.next != null){
            n = n.next;
        }
        n.next = end;
    }

    Node deleteNode(Node head, int d){
        Node n = head;
        if(n.data == d){
            return head.next;
        }

        while(n.next != null){
            if(n.next.data == d){
                n.next = n.next.next;
                return head;
            }
            n = n.next;
        }
        return head;
    }

    void printNodes(){ 
        Node n = this;
        while(n.next != null){
            System.out.println(n.data);
            n = n.next;     
        }
        System.out.println(n.data); //print out the last node
    }

    //For fun, to simulate how python print's a list
    // printed example [1, 2, 3]
    void listNodes(){
        Node n = this;
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        while(n.next != null){
            sb.append(n.data).append(", ");
            n = n.next;
        }
        sb.append(n.data);
        sb.append("]");
        System.out.println(sb.toString());
    }
}

Upvotes: 0

Views: 170

Answers (2)

Ekleog
Ekleog

Reputation: 1054

Based on the function you wrote, you should use it like ll = ll.deleteNode(ll, 1).

Besides, you do not need to take a head parameter, as this is already head.

If you want, you can also change the return type to void, replace the return head.next with data = head.next.data; next = head.next.next, and replace return head; with return; ; then you will be able to call it like you are trying to.

Here is the complete method:

void deleteNode(int d){
    Node n = this;
    if(n.data == d){
        data = next.data;
        next = next.next;
        return;
    }

    while(n.next != null){
        if(n.next.data == d){
            n.next = n.next.next;
            return;
        }
        n = n.next;
    }
    return;
}

Upvotes: 2

QuantumMechanic
QuantumMechanic

Reputation: 13946

When you call deleteNode() to delete the head of the list, the method doesn't do anything.

This code executes:

    Node n = head;
    if(n.data == d){
        return head.next;
    }

It returns the .next field of the head node but doesn't modify anything -- so it can't be deleting anything. When you call deleteNode() for anything other than the head you will reach the while loop and actually modify the list.

Upvotes: 2

Related Questions