1

I am trying to code a method for deleting the last Node in a linkedlist(for learning how to modify a linkedlist..I am not using the java library LinkedList class)..I tried to deal with the usecase where the passed linkedlist has only one Node.

However when I try to print the linkedlist before and after the removal, it gives the same output as if the node was not removed.

class NodeProcessing{
    public static void removeLastNode(Node f){
        if (f==null) return;
        if(f.next == null){//if linkedlist has single node
            f = null;
            return;
        }
        ...
    }

    public static void showList(Node first){
        System.out.println("linked list=");
        for(Node x = first; x != null; x = x.next){
            System.out.print(x.item+" ,");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Node a = new Node();
        a.item = "one";
        showList(a);
        removeLastNode(a);
        showList(a);
    }

}
class Node{
    String item;
    Node next;
}

Output:

linked list= one ,

linked list= one ,

update: when I used the debugger,I can see that the Node a in main() has address :Node@a61164 and the Node f inside removeLastNode() also has :Node@a61164

damon
  • 8,127
  • 17
  • 69
  • 114
  • You will find that it is a common question after you thinking, By Reference or By Value. When you set the Node null in Method "removeLastNode",it is just set the copy reference "f" to null, the real Node "a" is always point to the real value.By the way, you may change the Node.item in your Method.You may find some Heap and Stack details to look for the answer. – Sstx Jun 19 '13 at 06:11

3 Answers3

6

Setting f to null does nothing - that just changes the value of the parameter, which is just a local variable. It's important to understand that Java always uses pass-by-value for parameters - the value is a reference when the parameter type is a class type, but that reference is passed by value. Changing the parameter value to a different reference doesn't change the caller's argument.

Ideally you'd want to separate the concept of "the list" from "a node in the list" (just as the Java API does). That way when you call remove on a list, it mutates the list itself. In your current model of "a node is just the head of a list" there's no way you can remove the final node - you can't destroy the node itself.

The closest you could come would be to make removeLastNode return a Node reference - which could return null if the notional list is now empty.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • In addition to Jon's answer it would be advisable to set the removed element to null after you have removed the node. It would help avoid memory leaks. – Atul Jun 19 '13 at 06:14
1

The Node f is local variable in the following method

public static void removeLastNode(Node f)

Since it is a copy of the reference to the actual argument, the changes made to the parameters will not affect the arguments.

you are doing

f = null

where as

Node first

will be still pointing to the existing node. You are using the argument to print the linked list, Hence the result.

codeMan
  • 5,730
  • 3
  • 27
  • 51
0

You can use the java provided LinkedList data structure to do this.

    LinkedList items = new LinkedList();
    items.add("one");
    items.add("two");

    System.out.println(items);
    items.removeLast();
    System.out.println(items);

This will generate the desired output.

Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56