4

So I'm skimming through Cracking the Coding Interview to brush up on some interview stuff and I ran across this linked list implementation, and maybe it's been a while but it's completely going over my head. I understand most of it, except for one specific line, and it's throwing me off. I'll post the code below (for reference, the book doesn't mention language but it appears to be Java.)

class Node {
    Node next  = null;
    int data;

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

    void appendToTail(int d) {
        Node end = new Node(d);
        Node n = this;
        while(n.next != null) {
            n = n.next;
        }
        n.next = end;
    }
}

I'm a little confused on the line: Node n = this - I'm not sure what this is referring to, unless it's talking about next - why not just set it to null in that case?

vsminkov
  • 10,912
  • 2
  • 38
  • 50
secondubly
  • 983
  • 5
  • 18
  • 43

6 Answers6

3

this refers to a specific instance of an object of a class. Since objects are constructed there can be multiple instances of a class, but using the this keyword allows you to obtain a reference to itself, meaning a reference to the the specific instance of the object whose method is being called.

The linked list is a collection of nodes that are, well, linked together. When you call appendToTail() the node will look at all of the Node objects linked to itself and follow the chain. For it to get a reference to itself to follow its own chain the this keyword is used.

You also ask why null isn't used in this case to initialize n. This would cause a NullPointerException when n.next is first called in the loop constraint, so instead its own reference is used as the starting point for the iteration of the linked-list.

This (pun intended) can be a confusing topic at first, but lets use the example you provided.

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

Let's pretend that there are 4 objects currently linked in our list and for simplicity's sake the Node object that appendToTail() is being called on is the head of the list. Here's the reference value of Node n that's held on each loop iteration from the above snippet.

  1. We're pointing to ourself - this
  2. Pointing to the second item in the linked list. - this.next
  3. Pointing to the following item - this.next.next
  4. Pointing to the last item in the list - this.next.next.next

The loop ended so currently the reference of n = this.next.next.next. We then set n's next value (where n is currently pointing to the end of the linked chain) to the new object we created at the beginning of our method, which makes it the new end of the list. (n.next = end is now equivalent to this.next.next.next.next = end).

Semi-Unnecessary Edit: This is explained in terms of Java. It appears that someone added the C++ tag after I wrote this answer

JNYRanger
  • 6,829
  • 12
  • 53
  • 81
2

This is Java.

"this" refers to the specific instance of the class in which the call is being made. In this case, "this" is in reference to the specific class Node you are dealing with. While the variable "end" creates a new and separate version of the Node class which is constructed using the passed int "d".

ballBreaker
  • 722
  • 1
  • 10
  • 29
  • Your second sentence is a bit misleading: `this` does not refer to the class itself, that would mean it's a static method. Instead it refers to the specific instance of the class that's calling the method. I don't mean to sound pedantic, but it's a confusing topic so just trying to make sure it's clear. – JNYRanger Aug 12 '15 at 18:35
  • Yeah fair enough. The sentence after cleared it up, but I edited in your suggestion. Thanks. – ballBreaker Aug 12 '15 at 20:16
0

Since this is a Linked List all Nodes are connected and you have a start Node (root). So when using it it would look like this:

Node root = new Node(6); //need an instance first
root.appendToTail(5);
root.appendToTail(3);
//6->5->3

Since this the nodes are connected I need one start Node and need to check if this has a next node when yes I need to search deeper. When a node did not have a next Node it is the current last one and can add my new Node. So this in Java refers to the current instance of a class. In my example the root Node(because I call root.appendToTail). So the method will search from the root Node (value 6) the next Node without a next Node (the one with value 3) and append it there. If I can get a child reference and would call child3.appendToTail the method would search from child3 instead of starting from my root.

When setting n to null and rewriting the while to go from this.next you would have a problem when the current node you use appendToTail did not have a next Node and an NullPointerException would be thrown.

mszalbach
  • 10,612
  • 1
  • 41
  • 53
0

Node n = this; means n object references to the object which is calling this method. So method is looping to next object till next object is null and assigning end node to the end.

Lets see

1 -- 2 -- 3 -- 4
*
|
*
obj

you have an obj object that is pointing to node 1. When u call obj.appendToTail(5)

Node end = new Node(d); //new node is created to add to the end.
Node n = this; //local n object is referenced to node 1(or obj)
while(n.next != null) {
   n = n.next;
}
//n here is node 4 since there is no next node to 4
n.next = end; //node 5 is tail now

End result: 1 -- 2 -- 3 -- 4 -- 5

Elbek
  • 3,434
  • 6
  • 37
  • 49
0

Any Node instance can call appendToTail().

Notice howebet, here in fact Node does not append itself to tail of the list, what happens here is that new node is created and added to tail, not the one on which method is invoked.

For this to happen, first we need to find the tail of the list given the current Node.

  // n is pointing to current Node
  while(n.next != null) {
            n = n.next;
        }

Once we find node which has next == null, this is tail of the list so we can now append new Node to the tail:

    // n points to current tail before next line is invoked
    n.next = end;

As to why there is line:

    Node n = this;

Well since there is no LinkedList class which maintains reference to the head, you have to be able to iterate from any given Node. That is what happens here, you start iteration from Node on which appendToTail is called, but that Node can be anything at this point, from head to tail.

As a side note, if you implement Linked List by hand, make sure to actually have class LinkedList which will offer methods such as add, get, size, appendToTail and so on, rather then putting these into Node class.

John
  • 5,189
  • 2
  • 38
  • 62
0

As you can see in this code

class Node {
   //

   void appendToTail( int d ) {
       Node *end = new Node( d );
       Node n = this;
       // ...
   }
}  

Your class Node has a reference to a Node in it's definition.

The line: Node *end = new Node( d ); means inside a Node there is a reference to another node.

The line Node n = this; means inside a Node the reference to that node itself, is represented by this. Ergo, n is also a reference to said node itself.

Christopher Francisco
  • 15,672
  • 28
  • 94
  • 206