Dynamic Implementation of Linked List - java

class Nodetype
{
int info;
Nodetype next;
Nodetype(int i)
{
info=i;
next=null;
}
}
My textbook has this code to create Linked List dynamically.
The question is, when the programs is executed line-by line, it defines variable 'info' as type 'int' & then variable 'next' as Nodetype.
What is actually happening here?
does it mean that variable 'next' will contain -
Constructor 'Nodetype'
int info
Nodetype "next" where "next" will again have all 1,2,3 & then 3 will again have 1,2,3...and so on....till infinity?
I'm really irritated because I'm unable to understand how it works, can someone easily explain this?

Your code follows very well the definition of list: a list is null or an element followed by a list.
The "element", in your case, is defined by an int value, and the "followed by" part is the next variable; in Java variables (when they are not literals, as int values are) are actually pointers, so while they are not initialized they don't store any valid value and they don't point to any memory area (i.e. their value is null), so while the next variable is kept as-is your element is not followed by any other. To dynamically add elements to your list you need a pointer to the last element you added, otherwise you would not be able to find them again:
int i = 0;
Nodetype head = new Nodetype(i++);
Nodetype last = new Nodetype(i++);
head.next = last;
while (i<5) {
Nodetype temp = new Nodetype(i++);
last.next = temp;
last = temp;
}
while(head) {
System.out.println(head.info);
head = head.next;
}
Notice how, with the last few lines, you lose the head pointer and you have no way to get back the starting point of your list.. Keep that in mind when working with lists ;)

At first variable next doesn't point to any object(it points to null). At some time you will make it point to another node with next = new NodeType(number). The idea is that you use composition - you have one instance of class which has a reference to another instance. It is like nodeA points to nodeB, nodeB points to nodeC. Here you have three instances and the first instance has a reference to the second instance and the second instance has a reference to the third instance. The third instance is the last one and its next instance points to null.

the field next is a reference to an object of type Nodetype. at first it will point to nothing - since it is instantiated to null. when you assign a value to it, it will point to that value only, nothing will continue infinitely unless you create a cycle within the list.

You created class NodeType and inside of the class you defined object of that class. So that object (in your example next) will have int info variable NodeType next object and constructor.

It will contain Null, as the variable is not initialized to any value.

Nodetype is your class that defines the data a node instance will contain as well as the reference to the next node in the linked list. That reference to the next node will be an object of type Nodetype. Nothing too difficult here, this is the classic implementation of a Linked List.
You might want to check out this great linked list resource from Stanford.

The way this works is that the list is made up of single elements, each of which only has a pointer to the one that comes after it:
Nodetype next;
The information each element within the list actually holds is this:
int info;
You can think of a list like a "chain": it's not really a single object, but a compound object of a number of links. From each link, you can only see the next link (or, in case of linked lists that have references in both directions: the next and the previous link), so in order to have all elements available, you will have to keep the reference to the first element in the "chain".
Note: List objects are single objects that have a reference to the first link of the "chain".

next is a reference to another Nodetype instance. If next == null it means the current element is the last one in the list.
Let's see an example:
Nodetype node = new Nodetype(0); // i = 0, next = null
Nodetype anotherNode = new Nodetype(1); // i = 1, next = null
node.next = anotherNode; // now the first node has a ref to the second

#include<stdio.h>
#include<stdlib.h>
void print_list(int *arr,int *size,int *capacity)
{
printf("capacity = %d; size = %d; elements = ",*capacity,*size);
for(int i=0;i<(*size);i++){
printf("%d ",arr[i]);
}
printf("\n");
}
int * push_back(int *arr,int data,int *size,int *capacity)
{
int *b;
if(*size == *capacity){
*capacity = 2*(*capacity);
b = (int *)malloc(sizeof(int)*(*capacity));
for(int i=0;i<(*size);i++){
b[i]= arr[i];
}
b[*size]=data;
*size=*size+1;
print_list(b,size,capacity);
return b;
}
arr[*size]=data;
*size=*size+1;
print_list(arr,size,capacity);
return arr;
}
int main()
{
int size=0;
int n;
int x;
int *arr;
arr = (int *) malloc(sizeof(int));
int capacity=1;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&x);
arr=push_back(arr,x,&size,&capacity);
}
}
its working.

Related

Question about how Linked List references and stores data

I have a question about how Linked List stores datas and references each other.
public class LinkedList {
static class Node {
int data;
Node next;
// Constructor
Node(int d)
{
data = d;
next = null;
}
}
public static void main (String[] args) {
Node first = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
Node fourth = new Node(4);
Node fifth = new Node(5);
first.next = second;
second.next = third;
third.next = fourth;
fourth.next = fifth;
second = fourth;
System.out.println(second.data + "is fourth");
while (first != null) {
System.out.println(first.data);
first = first.next;
}
}
}
This code prints out
4 is fourth
1
2
3
4
5
However, I thought it should be
4 is fourth
1
4
5
Because I changed "second" value to "fourth" value
Anyone could explain what is happening here?
It's important to understand what happens when you call a method or create a new variable in memory in order to understand this behavior. Basically, there are two portions in memory where data is stored for something like this - the stack and the heap. The stack stores static information and has a fixed size, whereas the heap can store more complicated data (i.e. objects) and has no defined limitation on size, aside from the amount of memory you have available in the first place.
When you instantiate an object in Java, the object itself (the values and properties) are defined and stored in the heap, whereas a reference to the data, or the memory address of the object in the heap, is stored in the variable on the stack. This is why when you do something along the lines of
ExampleObject o = new ExampleObject();
System.out.println(o);
prints out something like ExampleObject#fa243dsf
This output isn't the object itself, which may have certain properties that you have defined, rather it outputs the reference to the object itself. When you do something like o.exampleProperty what you've done is dereferenced the object, meaning you told Java to go into the memory address of the object and get the exampleProperty value.
Now to come back to your question, the exact same thing happens with the next property on each Node, it's not storing the object itself, but a reference to that object. Let's imagine these are the memory address locations for each of the Node instances you created (just for example purposes, these aren't the exact locations where they are being stored by Java on your machine, nor are they proper memory addresses):
first has an address of 111
second has an address of 222
third has an address of 333
fourth has an address of 444
fifth has an address of 555
Now, your LL looks like this after assigning the next values:
first.next = Node#222
second.next = Node#333
third.next = Node#444
fourth.next = Node#555
fifth.next = null
Now, when Java reaches the line second = fourth, you haven't changed the object data itself, but merely the memory address that the variable second points to. What I mean by this is that second now points to address 444, and if you run System.out.println(second);, you will now see Node#444 be outputted to the console, however, you have not modified the original object that second referred to, nor have you modified the values of the LinkedList. This means that the value at memory address 222 has not changed, and so since first.next points to Node#222, the value of the Node created and stored at address 222 is the same as it was originally. This is why when you print out second.data at the end, you get the same value as fourth.data, but why the LinkedList itself hasn't changed to what you thought it would change to. If this explanation still wasn't very clear, I suggest you look into variables storing/passing data by reference vs by value, as that is the concept that outlines the behavior you are seeing vs what you had expected.

Java, what is happening internally when you do object = object?

I am implementing singly linked list in Java, and I have a problem.
In addition and removal of nodes, many people use temporary node like this:
public Object removeFirst() {
Node temp = head;
head = temp.next;
Object returnData = temp.data;
temp = null;
size--;
return returnData;
}
Why is this temp node necessary? At first glance, I think all I have to do in order to remove first element is to change second element into head node.
So my question is that in java, what does object= object mean? Do 2 objects become exactly same inheriting every fields and methods?
temp is not needed. It is used to obtain the data of the removed Node after the head variable is no longer referencing that Node, but that can be done without it:
public Object removeFirst()
{
Object returnData = head.data;
head = head.next;
size--;
return returnData;
}
what does object= object mean?
A class provides the blueprint for objects; you create an object from a class.
The new operator returns a reference to the object it created. This reference is usually assigned to a variable of the appropriate type
Assume that you have create new object head
When you copy one object to another object, then second reference is created to the object.
Node temp = head;
If you make second object (reference) as null,this object is still accessible with first reference (head).
Do 2 objects become exactly same inheriting every fields and methods?
Yes since only reference is different but object is same.
You can find more details in oracle documentation page
When you did not create object ( instantiate class):
When you create an object with new operator:
When you assign object to another object:

Explanation of a Java linked list class definition

I was given the following Java class definition to implement a single linked list program but I cannot get the full idea. I have written comments in the code poiting out my questions about it.
// ******************************************************************
// Definition of class Node<T>.
// ******************************************************************
public final class Node<T>
{
// This is a class with "generics" where T represents a type.
// A final class cannot be extended.
// A final variable behaves like a constant and can only be initialized at the time it is
// declared or within a constructor.
// I suppose this is the value of the node.
public final T v;
// I do not understand this. How is "next" defined "recursively"?
// Please help me visualize this situation.
// Can this variable indicate the end of the list, maybe with a null value?
public Node<T> next;
// Constructor.
public Node (T val, Node<T> link) {v = val; next = link}
}
// I suppose this is the value of the node.
public final T v;
Yes. Node is a parameterized class where the type of actual data it is holding is called T. So the value of the node is a variable having this type T. We could have a Node<Integer> which holds Integer value but also a Node<String> which would hold a String value. Node will behave the same way.
// I do not understand this. How is "next" defined "recursively"?
// Please help me visualize this situation.
// Can this variable indicate the end of the list, maybe with a null value?
public Node<T> next;
In a linked list, one node points to the next node in the list. This is why it is called "linked" list: there is a chain of elements all linked together. We might say it is defined recursively because one node points the next node, which in turn points to the next-next node, etc.
When the end is reached, there is no next node so it is null: the last element is the one having next = null. Note that there might not be a last element: one node could point to the first one and it would create a circular list.
As an example, let's say you want to build a linked list of 2 integer elements. The first element will be 1 followed by 3. You could write the following:
Node<Integer> firstElement = new Node<>(1, new Node<>(3, null));
// here firstElement.v will be 1 and firstElement.next.v will be 3

Array of Linked Lists in Java

I have to create an array of linked lists for a class in order to store a graph (adjacency list). We have to use Java. I can create the array and instantiate each linked list, but when I go to add the first elements to each one, every linked list gets changed, not just the one at the index of the array.
Node [] adjList;
for(i=0;i<adjList.length;i++)
adjList[i] = new Node(0,0,null);
this instantiates each new linked list [Node is my own class, with constructor Node(int head, int data, Node next) and extends LinkedList]
then i go to add the first values to each node:
for(i=0;i<adjList.length;i++)
adjList[i].setHead(i+1); // numbers 1 to end are the graph vertices
or
for(i=0;i<adjList.length;i++)
adjList[i].add(new Node(i+1,0,null);
I use print statements to debug the code
at the end of these loop I print off each Linked List, but for each one, the values come out to be the final one
ie. if adjList.length = 2, it would print out
[3,0,null] // adjList[0]
[3,0,null] // adjList[1]
[3,0,null] // adjList[2]
edit: here is the Node class
import java.util.LinkedList;
public class Node extends LinkedList{
private static int head;
private static int data;
private static Node next;
public Node(int h,int d,Node n) {
head = h;
data = d;
next = n;
}
public int getHead(){ // getNext() and getData() are the same
return head;
}
public void setHead(int h){ // setNext() and setData() are basically the same
head = h;
}
}
You have probably declared something within Node as static, so every instance ends up with the same shared value, rather than having its own value. However, this is just a guess - please post the code of Node so we can see what the problem really is...
when I go to add the first elements to each one, every linked list gets changed, not just the one at the index of the array
Although your code snippet doesn't show it, almost definitely you have an aliasing problem. The aliasing problem, which tends to bite beginners in almost all object-oriented languages, is the problem of referring to the same object with two different names i.e. two different variables pointing at the same object.
Now you may be wondering: what about array indices? The problem is with changing a variable at one array index and getting a change across all array indices, not a bunch of named variables. But, as Eric Lippert explains (for C#, which is quite similar to Java), an array really is a bunch of variables that you can refer to with an indexer expression rather than having to define a bunch of individual names. In a sense, int[] foo = new int[3] is like declaring foo0, foo1, and foo2, and indexing into foo just tells the compiler to pick the appropriate variable out of foo0, foo1, and foo2.
You may also be wondering how data could be shared between multiple Node instances, if your array indeed has multiple nodes in it. There are a few ways, and knowing which is pretty much impossible without the code for the Node class. As #DNA points out, there could be static data in the Node class, which is automatically shared across all instances. A Node object may also have a reference to underlying data. If you pass the same reference into all the Node constructors, they are all aliasing the same object in this way as well.

Java: How to refer to a class inside the class but of another element?

I'm not to sure on how to explain this but basically I am trying to refer to the List Classes front which is of Element A(can be from any list). But what happens is that when it goes through the Elements of the list it is comparing from two different lists and ends up not matching. ie compares original list which contains the front b to list containing element A. Now I'm just wondering about how i would get the front of Element A set to b so that i can compare where it is.
/*front is a dummy element used to keep position.
List is a class i have made under requirements of naming for subject.
i don't want a solution. I only want to know about how to do it.
This is what is an example code of whats causing the problem USED IN DRIVER PROGRAM
DLL.concat(DLL2);
it is basically getting DLL's front and going through the loop when it should be using DLL2's.
DLL and DLL2 are both Lists
***/
//will return the index of the Element for comparing
private int checkElement(Element A){
Element b = front;
int i = 0;
while (b != a && i<size)
{
b = b.next;
i++;
}
return i;
}
//edit: add
//size is the size of the list gets increased everytime a variable is added to the list on top of the dummy element.
//Item is a private class inside the List class. it contains the values: element,next, previous in which element contains an object, next and previous contain the next element in the list and the previous one (its a double linked list)
// this is what causes the error to turn up in the above method as im using two different lists and joining them.
public void concat(List L){
if (splice(L.first(),L.last(),last())){
size = size+L.size;
}
}
//this is the splice method for cutting out elements and attaching them after t
//just using the check method to assert that a<b and will later use it to assert t not inbetween a and b
public boolean splice(Element a, Element b, Element t){
if (checkElement(a) < checkElement(b)){
Element A = a.previous;
Element B = b.next;
A.next = B;
B.previous = A;
Element T = t.next;
b.next = T;
a.previous = t;
t.next = a;
T.previous = b;
return true;
}
else {
System.out.println("Splicing did not occur due to b<a");
return false;
}
}
So despite my comment, I see one glaring problem with this. You can't use equality operators on reference types. That is, anything other than a primitive type (double, int, etc). What happens is you're comparing the address of the instance and unless they are literally the same object (same address in memory), it isn't going to return true, ever. Maybe that's what you want, but I suspect not. You need to override the method
public boolean equals(Object obj);
and use that to compare two instances of a given class. Am I correct in my assumptions?
Edit Ok, I think my original guess was correct. It works if they are from the same list because they end up being the same elements (stored in the same memory location). You need to use equals() or !equals() rather than == and !=. Try that, and see if it solves your problems. Also, don't just use them, you must override equals to actually compare the elements internal properties.

Categories