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.
Related
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
I am a couple of java data data structure exercises.
Here is the exercise I am currently doing
Add an array-linked hierarchy to the overall structure. Use the following names: AbstractNodeArrayMyList, NodeArraySorted, and NodeArrayUnsorted
I've already implemented abstract array list, sorted array list, unsorted array list, abstract linked list, sorted linked list, and unsorted linked list.
However I am confused about what this array linked structure or node array is.
I tried doing a google search for an array linked list or structure but all I got was searches that resulted in difference between array and linked list. Can anyone clarify or confirm my initial opinions of what this node array or array linked structure actually is?
When I think of a node, I think of a node in a linked list, something that contains data, and the reference to the node it is connected to, something like
from these lecture notes for ListNode.java
public class ListNode {
int data;
ListNode next;
public ListNode() {
this(0, null);
}
public ListNode(int data) {
this(data, null);
}
public ListNode(int data, ListNode next) {
this.data = data;
this.next = next;
}
}
And when I think about array. I think about something that supports random access, like you can access any element in the array and it would take constant time. So would a node array look something like this? (you define the ListNode as a private inner class) and the outside class would look like
public class NodeArray {
private ListNode[] elementData;
...
private class ListNode {
....
}
}
I didn't think my initial idea was right because the whole idea of the generic array list is that it would work with any type of data. Why have a special class for ArrayNode then?
Linked lists can either be array-based or pointer-based. If you've studied C++, you're probably familiar with pointers. They also exist in Java, but they're controlled by the java compiler behind the scenes, so you don't explicitly reference them. If you think of these structures as arrays vs linked lists, you'll probably confuse yourself. You really should be thinking arrays vs pointers. I know you asked this question in java, but since you don't explicitly use pointers in java, it might make more sense to see an example in C++.
Let's say you have a list classes, ArrayList and PointerList. ArrayList might be set up like the following:
class ArrayClass
{
public:
// Default constructor
ArrayClass();
// Returns the next item in the list using currentPos
// If the end of the list is reached,
// currentPos is reset to begin again.
ItemType getNextItem();
//other methods
private:
int length; // Number of items
ItemType info[MAX_ITEMS]; // Array of items
int currentPos; // List iterator
};
The implementation of getNextItem() using an array-based linked list would look something like this:
ItemType ArrayList::getNextItem()
{
currentPos++;
return info[currentPos];
}
With this implementation, the method returns a copy of the object stored at the index currentPos points to. The index number itself (currentPos) is never revealed to the code that called it, and since the returned object is a copy of the stored object, any changes made to the copy won't automatically be made to the stored version. To store the updated version of the object, the user would have to delete the stored object at info[currentPos], then add the new version in its place. Hopefully this makes sense.
Now let's look at PointerList. It might be defined like so:
class PointerList
{
public:
// Default constructor :
PointerList();
// Returns the next item in the list using currentPos
// If the end of the list is reached,
// currentPos is reset to begin again.
ItemType getNextItem();
//other methods
private:
int length; // Number of nodes on list
NodeType* listData; // List head ptr
NodeType* currentPos; // List iterator
};
The implementation of the pointer-based getNextItem() could look like this:
ItemType PointerArray::getNextItem()
{
ItemType item;
if (currentPos == NULL)
{
currentPos = listData;
}
else
{
currentPos = currentPos->next;
}
item = currentPos->info;
return item;
}
This implementation will return the address of the item in the linked list. Using pointers will return an object by reference, whereas using an array will return an object by value. Any changes made to the object in this implementation will immediately be made to the stored object since the code that called this method has direct access to the stored object.
In both of the above examples, don't worry about ItemType and NodeType. These aren't special data types in C++. They could just as easily be Foo or Car, etc. Also, they can both refer to the same data type.
I hope this makes sense. Let me know if you have further questions.
I'm working with double-ended queues for an assignment, and we're running into an issue where the object reference is disappearing from a node after being passed through an extremely simple method.
Some important definitions:
class Node {
String s;
Node prev;
Node next;
...
}
class Sentinel extends Node {
Node prev;
Node next;
//Constructor uses that of Node
}
class Deque {
Sentinel start;
...
}
One method we are writing removes a Node from a deque, based on the given string.
In deque:
public void removeSorted(String toRemove) {
// System.out.println(this.start);
// System.out.println(this.start.next);
this.start.next.removeSorted(toRemove);
}
The commented out println's show the correct Sentinel and Node.
Then, in Node:
public void removeSorted(String toRemove) {
if (this.s.equals(toRemove)) {
// System.out.println(this.prev);
// System.out.println(this.prev.next);
this.prev.next = this.next;
this.next.prev = this.prev;
} else if (this.s.compareTo(toRemove) > 0) {
throw new RuntimeException("String does not exist in these nodes!");
} else {
this.next.removeSorted(toRemove);
}
}
The println for this.prev outputs the Sentinel on the first recursion, as expected. However, this.prev.next outputs null instead of the Node.
This function only fails when trying to remove the first Node, directly after the Sentinel. If you try to remove any other Node, it works correctly, and trying to call this.prev.next results in a non-null answer.
Why does the reference disappear when passing to the function (immediately after), since we've shown that the reference is there directly before calling the function?
Either your question code is wrong, or you have same fields in both Node and in Sentinel. This means, that these two are different:
start.next is next field of Sentinel class, which hides field with same name from Node class.
start.next.prev.next is also a field of start, but now it is the field of Node class, because you access it through Node reference.
Remove prev and next from Sentinel. Actually remove the whole Sentinel, it looks like you use to to "remove" the String s, which is impossible, you can't "remove" super class fields. Or if you need/want sentinel, see below for alternative design.
Also, this demonstrates why you should use getters and setters instead of accessing fields directly... Your IDE probably has nice refactoring tool to add getters etc (right click on field, see "Refactor" submenu), use it! And if your IDE does not have that, switch to one which does (I prefer NetBeans, but Eclipse and IntelliJ are worthy too), writing Java without such an IDE is an exercise in masochism...
Also, in Java avoid that kind of inheritance. You should probably have this kind of overall design:
interface NodeInterface {...}
public class Node implements NodeInterface {...}
public class Sentinel implements NodeInterface {...}
Then in the NodeInterface, define getters and setters, which should take as parameters as well as return NodeInterface type. Sentinel class would not support all interface methods of course, so those methods can either return null;/do nothing, or throw new IllegalStateException("Sentinel does not support Xxxx."); depending on method and if calling that method for sentinel is bug in calling code or not (better start with throwing exception).
If this is school work and you have not gone over interfaces yet, then replace interface NodeInterface with class NodeBase (preferably abstract), but in "real world" this would be bad code, because Java does not support multiple inheritance.
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.
Hi I have 2 classes in Java, Gossip and Node, I want that Gossip will hold a list of all the objects of Node class and I want that each Node object will also have that list. I tried to write it in the following way:
public class Node {
private Boolean val = null;
private LinkedList<Node> list;
static Random rand = new Random();
public Node(LinkedList<Node> list) {
this.list=list;
}
... the rest of Node functions ...
}
and in the Gossip contractor:
public class Gossip {
private int count;
private int n;
private LinkedList<Node> list;
public Gossip (int n) {
this.count = 0;
this.n = n;
list = new LinkedList<Node>();
for (int i=0; i<n; i++){
list.add(new Node(list));
}
}
... the rest of Gossip functions ...
}
Since I'm used to C++ I am not sure how it works here and whether this will work like a pointer and each Node will have a full list or will each Node will only have a list with the Nodes created before it and itself. Also, I don't need to change the list on the program, just to read from it, but it's interesting, will a change that one Node does in the list will affect all other Nodes's lists?
There is only one list of nodes and all the nodes have references to this single list.
This is because in the Node constructor the assignment this.list=list; doesn't create a copy of the object - it simply makes this.list the same as list, but remember they both are references (on the stack) to the object (on the heap).
Therefore, if you change the list through one of the nodes, all other nodes will see the change.
There is only one list created in new LinkedList<Node>(); per one Gossip. Later it is passed by reference (pointer like), thus it same list everywhere.
Is the Node class used outside of the Gossip class? If not then you might want to consider making Node a private inner class of Gossip. That will simplify things because Node instances can access the list in Gossip without having to have their own reference to it. You'll have to define the list as final to do this.
All variables / fields in java that are derived from java.lang.Object are "references" and that is basically exactly the same as a pointer in C++. (Not to be mixed up with C++ references which are also only pointers but with a special semantic)
That means int, float and all other primnitives are values and not pointers/references, ofc.