I was curious as to learn how you would add multiple ints to a Node in a LinkedList in java (single circular). I had found a thread on SO and was reading on it but wasn't sure exactly how it worked. Thought I would revive the question to see if I can get an answer.
This is my Node class
public class LinkedList{
private class Node{
private int pid;
private int time;
private Node next;
public Node(int pid, int time){
this.pid=pid;
this.time=time;
}
}
int size;
Node head;
This is my add which I'm just trying before I do any remove or anything like that.
public void add(int pid, int time) {
Node curr=head;
Node newNode=new Node(pid, time);
if(head==null){
head=newNode;
newNode.next=head;
}//end if
else{
while(curr.next!=head){
curr = curr.next;
}//end while
curr.next=newNode;
newNode.next=head;
}//end else
size++;
}//end add
}
This is what I have so far but when I try to input the two ints I get a null pointer exception at the private int time Am I doing something wrong? I'm reading in a file and then storing the two ints in a single node and then doing the same until the file is completely read through. I have the file reading in just fine and I have the two ints stored as ints from the file but I can't seem to get it to store the ints in the Node quite yet
How have you initialized head? Did you do Node head = new Node()?
If you make a custom constructor, Java does not add the default constructor anymore. You have to define that again.
You can instead do Node head = null;
Related
I am studying the linked lists,and I'm having a little problem understanding references and pointers in Java (and also have some questions for which I can't find answer on the internet.) Namely,I have a class LinkedList that uses class Node like this:
public class LinkedList {
public Node head;
public LinkedList(int data) {
head = new Node(data);
}
}
and this is my Node class:
public class Node {
public int data;
public Node next;
public Node(int data2) {
data = data2;
}
}
I also have method toStringLL() inside LinkedList which looks like:
public void toStringLL() {
LinkedList l=this;
while(l.head.next != null) {
System.out.print(l.head.data+"->");
l.head = l.head.next;
}
System.out.print(l.head.data);
System.out.println("");
}
I don't understand why this toStringLL() changes my head of linked list,when I am iterating through it with l.head=l.head.next? Shouldn't my head stay the same?I thought that when I write LinkedList l=this,I can freely iterate through l,without affecting this(or am I wrong?) Now when I use Node n=this.head instead of LinkedList l=this,it works,but I have difficulty figuring out why that works and the previous doesn't.. Can someone explain to me the difference between these two?
I don't understand why this toStringLL() changes my head of linked list,when I am iterating through it with l.head=l.head.next?Shouldn't my head stay the same?
When you make the assignment
LinkedList l = this;
you are not creating a new LinkedList object. You are just defining a references to the existing LinkedList object.
Therefore, l.head = l.head.next does exactly the same as this.head = this.head.next. Both change your original list.
On the other hand, when you write
Node n = this.head
you are not changing the head of your List. You are declaring a variable that initially refers to the head of your List, but when you change that variable to refer to other Nodes of your list, the head variable of your list (this.head) remains unchanged.
When you set
l.head=l.head.next;
you change your head.
I have checked few posts that we have in SO.
Insert new node at the beginning of Linked-List
How do I insert a node at the beginning of a linked list?
And implemented a simple LinkedList in java that works just fine.
What I can't get my head around is how adding a new Node to the beginning of the LinkedList would actually work.
Here is how my code snippet for adding a Node to the beginning of the LinkedList looks like:
public class SinglyLinkedList
{
//Private variable to keep tab of the HEAD of the linked list.
private ListNode head;
//Private variable to keep track of the node count in this singly linked list.
private int length;
.
.
.
/**
* Insert a ListNode at the beginning of this List.
*/
public synchronized void insertAtBegin(ListNode newNode)
{
//Set current head as the next of input ListNode
newNode.setNext(head);
//Set the input ListNode as the new head of this SinglyLinkedList
head = newNode;
//Increment the SinglyLinkedList length
length++;
}
.
.
.
}//End of class SinglyLinkedList
The ListNode class represents a Single Node like so:
/**
* Represents a Node of the Linked List.
*/
public class ListNode
{
private ListNode next;
private int data;
/**
* Constructors
*/
public ListNode()
{
next = null;
data = Integer.MIN_VALUE;
}
public ListNode(int data)
{
next = null;
this.data = data;
}
/**
* Accessor methods.
*/
public int getData()
{
return this.data;
}
public void setData(int data)
{
this.data = data;
}
public ListNode getNext()
{
return next;
}
public void setNext(ListNode listNode)
{
this.next = listNode;
}
public String toString()
{
return Integer.toString(data);
}
}//End of class ListNode
The 2 lines that really confuse me are:
//Set current head as the next of input ListNode
newNode.setNext(head);
//Set the input ListNode as the new head of this SinglyLinkedList
head = newNode;
The more I try to analyze these two lines, I feel it will create a circular reference structure instead of pushing in the "newNode" in place of "head".
May be I don't quite understand how Java references are passed around.
Is there an explanation as to why the above two lines won't end up in a circular reference?
It seems you understand conceptually how the LinkedList gets a new head node. Your question is more related to Java itself.
Remember that Java is pass-by-value; When you are passing objects around, you aren't passing the value of the object - you are passing the value of the pointer to that object. Is Java "pass-by-reference" or "pass-by-value"?
So with that in mind, let me break down those 2 lines.
newNode.setNext(head)
The value in head is a pointer to a node. So the setNext function is receiving, in accordance to pass-by-value, a pointer to a node. It is NOT receiving a pointer to head.
head = newNode;
in this line, we reassign head's VALUE to be a POINTER to the newly created node. The value in newNode.next is still a pointer to the previous head.
You are encountering a very common confusion with Java, and believe me it is VERY VERY common (hence the 2k upvotes on the SO I referenced above). I hope this addresses your main source of confusion!
Imagine you have the following LinkedList:
2 -> 3 -> 4 -> 5
and you want to insert a node with a value of 1 at the beginning. Let's call this node newNode.
Now look at this line: newNode.setNext(head); You are making newNode's next value point to head, which in this case is pointing to the node with a value of 2. This is what your list looks like now:
1 -> 2 -> 3 -> 4 -> 5
However, head is still pointing to the node with the value of 2, so you have to fix that by making head point to the node with a value of 1, which is newNode. That is what the line head = newNode; does.
When your list is moving from right to left, i.e. 1 then after new node insertion it becomes 2->1 then after fresh insertion it becomes 3->2->1, In this case you need to take care of two things only : head (the first element of the list) & temporary node which is to be inserted next. Here is the pseudo code for that:
` while(you_want_to_insert_new_node) //temporary is the node to be inserted freshly
{
Insert(temporary->data); //Insert data in temporary node
temporary->next=head;
head=temporary;
}
`
When your list is moving from left to right, i.e 1->2 then it becomes 1->2->3 and so on, you need to take care of 3 things: head, the current node and the temporary. Here is the pseudo code for that:
`
current=head;
while(you_want_to_insert_new_node) //temporary is the node to be inserted freshly
{
Insert(temporary->data); //Insert data in temporary node
current->next = temporary;
current=temporary;
}
So I was wondering how I could create a new empty linked list, using my class definition of List and node, with a first head node pointing to null without having to hold any integer value. The thing is I'm not allowed to change the given methods or add any to the definition, so whenever I create a list, in the constructor I'm not sure how I'm supposed to asign head to null. Here's part of the codes:
public class Node {
private Node next;
private int key;
Node(Node nxt, int keyValue) {
key = keyValue;
next = nxt;
}
Node getNext() {
return next;
}
int getKey() {
return key;
}
void putNext(Node nxt) {
next = nxt;
}
}
Class List
public class List {
private Node head;
List() {
head = new Node(null, -1); // arbitary value for head
head.putNext(null);
}
This is what I came up with. I just assign a random value to variable key in head node. But if I do this, it will kinda mess up with my later methods that used recursive like deletion or finding sum or find max, min, etc
Is there any other way around I can do to deal with this issue?
In an Empty Linked List Head is Just a pointer which points to Nothing. You dont need to worry about creating an object to which current head points. Just create a head pointer and assign it to NULL. When you are actually adding a Node assign the address of first node to Head. Thats it...
public class List {
private Node *head;
List() {
head = NULL;
}
}
I have a question regarding the output of the following program. The output is null. This is what I thought as well. Im thinking its because the methods called before display simply modify a copy of head and not head itself. Im assuming that I could get around this using a this.head= something right?
Heres the code:
public class List {
private Node head;
public List (){
int max=3;
int i;
head=null;
Node aNode=new Node(0);
for (i=0; i<max; i++) {
aNode.setNum(i);
add (aNode);
aNode.setNext(null);
}
}
public void add(Node aNode) {
Node temp;
if(head==null)
head=aNode;
else {
temp=head;
while(temp.getNext()!=null)
temp=temp.getNext();
temp.setNext(aNode);
}
}
public void display() {
Node temp=head;
while(temp!=null) {
System.out.println(temp.getNext());
temp=temp.getNext();
}
}
}
public class Node {
private int num;
private Node next;
public Node (int n) {num=n; next=null;}
public int getNum() {return num;}
public void setNum(int n) {num=n;}
public void setNext(Node n) {next=n;}
public Node getNext() {return next;}
}
public class Driver {
public static void main(String args[]) {
List aList=new List();
aList.display();
}
}
The add relies on receiving a new Node with next being null. So move Node aNode = new Node(); inside the for-loop.
Some sanitary remarks.
(Unimportant) Use current instead of temp, or anything else.
Fields in classes are by default null/0/0.0/false.
Before I answer your question, here is a side note...
Im thinking its because the methods called before display simply modify a copy of head and not head itself.
This is NOT correct.
Here is why...
public void display() {
// Basically, this says, make temp a REFERENCE of head...NOT A COPY!!!!
Node temp=head;
while(temp!=null) {
System.out.println(temp.getNext());
temp=temp.getNext();
}
}
Now, to answer your question, the reason temp is null is because head is null. And the reason head is null is because you never initialize it.
From you constructor...
public List (){
int max=3;
int i;
// Here you're saying "set head to null".
// So when you call display, head is NULL. You MUST initialize this.
head=null;
Node aNode=new Node(0);
for (i=0; i<max; i++) {
aNode.setNum(i);
add (aNode);
aNode.setNext(null);
}
}
Look at this code from the constructor:
Node aNode=new Node(0);
for (i=0; i<max; i++) {
aNode.setNum(i);
add (aNode);
aNode.setNext(null);
}
You create one new node, and then keep trying to add that node to the list. You need the first line to be inside the for loop, so you create lots of nodes. After the constructor completes, your list only contains one node, with the value 3. Then later, in display():
System.out.println(temp.getNext());
You start by calling getNext() on the first node. Since there's only one node, getNext() returns null, which is what you print out. You should replace this line with
System.out.println(temp);
The error is nothing to do with the this keyword at all. You only need this.foo (when foo is some data member of your class) to disambiguate when you have a both a member and a local variable or parameter with the same name.
I have a problem understanding an exercise. I have to develope a linear linked list. But I do not have to to distinguish between list and node.
The constructor Node should create a node and prepend it to the list that is passed as a parameter.
Normally I would go through the list and append a node at the end of it. Here is my code.
class Node{
Object data;
Node link;
public Node(Object pData, Node pLink){
this.data = pData;
this.link = pLink;
}
public String toString(){
if(this.link != null){
return this.data.toString() + this.link.toString();
}else{
return this.data.toString() ;
}
}
public void inc(){
this.data = new Integer((Integer)this.data + 1);
}
}
Maybe I have just learned to much today and my brain can't take more inforamtion:D please help!
You need modify the next pointer of the node to point to the list that is passed in as a parameter.
This is in fact what your code is already doing. I have tried running it and it gives the correct result. :)
You might want to consider including a separator in your implementation of toString so that the output is still clear when the numbers in the data get larger than 9.
I am not sure what you are asking but i think this is what you want so here it goes.
Lets say you already have the head
Node head = ...
you can append to this by doing
head = new Node(..., head)
Notice I am assigning head again so now the head points to the newly created node.