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.
Related
I am currently working on an assignment for class where I am tasked with creating an empty List that has a Comparator as an argument then creating an add method for that sortedDoublyLinkedList where I am passed an argument and I have to iterate through the list to find where the new node fits. I'm not very familiar with Comparator so I'm a bit clueless as to how to add elements to my DoublyLinkedList because I cannot access the Comparator the way I though I was supposed to. Here is what I have now. Here is what I currently have.
public class SortedDoubleLinkedList<T> extends BasicDoubleLinkedList<T> {
Node<T> head=null;
Node<T> tail=null;
SortedDoubleLinkedList<T> sDLL;
public SortedDoubleLinkedList(Comparator<T> comparator2){
sDLL=new SortedDoubleLinkedList<T>(comparator2);
}
public SortedDoubleLinkedList<T> add(T data){
Node<T> newNode=new Node<T>(data);
//I have to iterate through the list and find where the new element data fits
if(head!=null&&tail!=null) {
Node<T> cursor=head;
while(cursor!=null) {
//the following code doesn't work
if(sDLL.comparator2.compare(data, cursor.getData())==0) {
}
}
}
else {
head=newNode;
tail=newNode;
}
return this; //return the SortedDoubleLinkedList<T>
}
Comparator is an interface. You need to implement a class that will provide that interface.
class Whatever implements Comparator<TYPE> {
int compare(TYPE a, TYPE b) {
... code to decide whether a is less than,
equal to, or greater than b ...
}
}
Where I wrote TYPE, you need an actual type. Just supplying the type variable T is not going to get you to runnable code, which I assume is your goal. Ultimately you've got to say what type will go in your list. So I'd be expecting something like (in your code above)
public class SortedDoubleLinkedList extends BasicDoubleLinkedList<String> {
where you're storing Strings in your list. And then TYPE in my code is also String.
ALTERNATIVELY
You can leave your SortedDoubleLinkedList generic (in terms of T) but ultimately you want to get concrete about it, maybe
SortedDoubleLinkedList<String> = new SortedDoubleLinkedList(new Whatever());
but the Comparator is still going to need to be a Comparator<String> (or whatever type you choose).
This was asked in an interview.
Can you implement/create an object in java which is similar to Array class in java.
basically we should be able to iterate over the object like we do with arrays and getValue() or putValue() methods should be able to directly work on index of the object created.
ex: below operation should be performed with created object.
int ar[] = new int[5];
for(int i=0; i<5; i++){
ar[i]=i;
}
Hint given was to use linkedlist data structure.
in simple words its the similar like ArrayList class implementation.
can anyone give me an idea how can we do this?
He was asking about nested objects. please read about decorator pattern. please see the below example.
public interface NodeInterface{
// your methods
}
public class Node implements NodeInterface{
private NodeInterface node = null;
// your methods
}
There every node contains nested object of same type. last object that have no object points to a null. you can traverse untill you find a null.
I've asked a similar question before which has been answered, and it has to do with the concept of nodes and linked list. My question can be found by following this link
Problems understanding concept of nodes and linked list
I accepted the answer because it helped me visualize what the linked list would look like and what my Node class would look like.
When you do make the node object, you can then make custom classes to change to value of what that node is storing, as well as retrieving and displaying the data stored in the node.
The node class would look something like this
public class Node{
private int val;
private Node node;
public Node(int val){
this.val=val;
}
public Node(Node node, int val){
this.node = node;
this.val = val;
}
public Node getNext(){
return node;
}
public int getVal(){
return val;
}
}
Obviously you can modify the code to store anything you want, but this is probably what the interviewers were looking for.
Using LinkedList it should looks like:
LinkedList<Integer> linkedList = new LinkedList<>();
for(int i=0; i<5; i++){
linkedList.add(i);
}
However, I'm giving you the link for beginners in which you can lear everything about the java util package. Good luck.
As a sample, I am developing a simple MySortedSet in java which implements SortedSet interface. It is backed up with a simple array which is E[] array.
I have several questions regarding that:
This is the class: (I am not writing entire code, instead of related parts)
public class MySortedSet<E> implements SortedSet<E>, Iterator<E> {
private E[] array;
private Comparator<? super E> _comparator;
private int size = 0;
private int capacity;
#SuppressWarnings("unchecked")
public MySortedSet() {
this.capacity = 10;
this.array = (E[]) new Object[this.capacity];
// this.array = Array.newInstance(Class<E> var,int size);
// We have to get Class<E> from outside caller.
}
}
Since it accepts all sort of type from primitive to reference types etc. I am not really sure when removing an item, assigning null is a good way in place of the removed item. Since Java initializes primitive types with 0. So null only works for reference types.
Below is probably very bad design:
#Override
public boolean remove(Object o) {
int indexOfElement = this.find(o);
boolean removed = false;
if (indexOfElement != -1) {
this.array[indexOfElement] = null;
removed = true;
}
return removed;
}
Can someone tell me what the best way is to remove an element from an array?
Edit:
Honestly what I am thinking to remove an element from an simple array is like copy the entire array without the removed item into a whole new array but I am not sure how efficient it would be in terms of performance and etc.
It kinda depends on the context of how you want to use your array. For example, if you are going to be iterating over the array and using the contents of it for standard methods like Arrays.sort(), they might generate NullPointerExceptions if you have null values in your array.
If you really want to remove items from an array in a safe way, I'd suggest changing your array to an ArrayList like this...
ArrayList<Object> list = new ArrayList<Object>();
list.add(object);
list.remove(object);
As this will actually remove the item from the list completely - no nulls or anything will remain, and performing methods like length() will return a real value.
For instances when I have used an array, I set the value to null, and ensure that all iterations over the array check that value != null before I try to query it. After setting the nulls for the removed items, I usually loop over the array and manually sort all the nulls to the end of the array, and then do System.arraycopy() to resize the array. This will leave you with a new array of the correct size, with all items in it except for the removed ones. However, I suggest this only if you really must use an array, as it is slower and introduces much greater potential for errors and NullPointerExceptions.
Alternatively, if you're not worried about sort-order, you can simple move the last item in the array over the top of the item you want to remove, and keep a count of the real array size. For example...
Object[] array = new Object[20];
int realSize = 15; // real number of items in the array
public void remove(int arrayIndex){
array[arrayIndex] = array[realSize-1];
realSize--;
}
This method removes an item in the array by 'replacing' it with the item in the last position of the array - its very quick and pretty to implement, if you don't care about sort order.
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.
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.