So the concept of my question is: Let's say we have nodes. Each node has an array of integers. Now, we must add an integer to end of the array. How do we do that?
Here's what I've done so far:
Created class Node:
public class Node {
private int[] data;
Node next;
public Node(int n, Node nxt) {
data = new int[n];
next = nxt;
}
}
Then the dynamic array list class:
public class DynamicArrayOfInts {
private Node head = null;
private int numOfElementsPerNode = 0;
public DynamicArrayOfInts(int elementsPerNode) {
numOfElementsPerNode = elementsPerNode;
}
public void add(int e) {
}
}
You should add an attribute in the Node class to know the current index you are for the current Node's array. I would also add an attribute in your DynamicArrayOfInts to keep a reference for the current node.
Then in your add method, check if the array that the current node have is not full (it can be done easily because you know the value of the index and the number of elements per node).
If it's not the case (or if the head is null for the first add call), create a new node and add the element in its array, otherwise just fill the next slot of the array for the current node.
This is how I would implement it.
class DynamicArrayOfInts {
private Node head, current;
private int numOfElementsPerNode;
public DynamicArrayOfInts(int elementsPerNode) {
if(elementsPerNode <= 0)
throw new IllegalArgumentException("elementsPerNode must be > 0");
numOfElementsPerNode = elementsPerNode;
}
public void add(int e) {
if(head == null){
head = new Node(numOfElementsPerNode, null);
head.data[head.index++] = e;
current = head;
return;
}
if(current.index == numOfElementsPerNode){
Node n = new Node(numOfElementsPerNode, null);
current.next = n;
current = n;
}
current.data[current.index++] = e;
}
#Override
public String toString(){
StringBuilder sb = new StringBuilder();
Node n = head;
while(n != null){
sb.append(Arrays.toString(n.data));
n = n.next;
}
return sb.toString();
}
private static class Node {
private int[] data;
private int index;
private Node next;
public Node(int n, Node nxt) {
data = new int[n];
index = 0;
next = nxt;
}
}
}
A small main to show how it behaves:
public static void main(String[] args){
int[] toAdd = {5,7,10,-1};
DynamicArrayOfInts d = new DynamicArrayOfInts(2);
for(int i : toAdd){
d.add(i);
System.out.println(d);
}
}
Output:
[5, 0]
[5, 7]
[5, 7][10, 0]
[5, 7][10, -1]
Unfortunately you have to create a new array in this case (yes, I feel your pain) which will have one more element than data. You will have to copy the content of data into your new array and set the last element to your int value. This is not too elegant, this is why Mureinik suggested that you should use an ArrayList of Node (ArrayList<Node>) instead. I can even enhance his suggestion to make your solution more general and tell you to use an AbstractList<Node> instead and instantiate it with ArrayList, but this might be too advanced compared to your current level (no offence, we all have been there). As of your exact question, I imagine a method like the following in your Node class to deal with this problem.
public void push(int newValue) {
int[] newData = new int[data.length + 1];
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
newData[data.length] = newValue;
data = newData;
}
Related
I am trying to write a program that takes an integer and inserts it into the second position in the linked list, but when I run my program it prints out (127, ) when I want it to print out (12, 7). I know it is probably an easy fix, but I am unsure of how to fix this small error. I have tried switching words around like head and tail and next, but nothing I do seems to work. Any input would help a ton!
public class IntSinglyLinkedList {
private static class Node {
private Integer element;
private Node next;
public Node(Integer e, Node n) {
element = e;
next = n;
}
private Node head = null;
private Node tail = null;
private int size = 0;
public IntSinglyLinkedList() { }
public int size() { return size; }
public void addSecond(Integer e) {
if(head == null)
return;
Node Final = new Node(e, head);
Final.next = head.next;
head.next = Final;
}
public static void main(String[] args) {
IntSinglyLinkedList sl = new IntSinglyLinkedList();
sl.addFirst(12);
sl.addSecond(7);
System.out.println(sl.toString());
}
}
My toString also looks like this if this is any help!
public String toString() {
StringBuilder sb = new StringBuilder("(");
Node walk = head;
while (walk != null) {
sb.append(walk.getElement());
if (walk != tail)
sb.append(", ");
walk = walk.getNext();
}
sb.append(")");
return sb.toString();
}
my addFirst method
public void addFirst(Integer e) {
head = new Node(e, head);
if (size == 0)
tail = head;
size++;
}
Why aren't you just using a LinkedList?
LinkedList<Integer> ll = new LinkedList<>();
ll.add(12);
ll.add(1, 7);
System.out.println("LinkedList is: " + ll.toString());
Output would be: LinkedList is: [12, 7]
You never update your tail element after your addFirst, so the , will not be printed after the first element.
You have to add tail = Final; in your addSecond method to make this particular example to print correctly.
That answers the specific question of why you get (127,) printed instead of (12, 7) in this particular case.
However, it is hard to see where you are going with this. Are you planning to write a new method for every element you want to add? It would make more sense to have a general add:
public Node add(final Integer i) {
final var node = new Node(i, null);
if (size == 0) {
head = node;
} else {
tail.next = node;
}
tail = node;
size++;
return node;
}
I am working on a project for my Data Structures class that asks me to write a class to implement a linked list of ints.
Use an inner class for the Node.
Include the methods below.
Write a tester to enable you to test all of the methods with whatever data you want in any order.
I have to create three different constructors. One of the constructors is a copy constructor. I have my code down below showing what I did but I'm not sure I wrote this constructor correctly. I also have a method called addToFront one of the many methods I need to implement in this project. Can someone let me know what I would need to write for the copy constructor? I have no idea what I need to write for a copy constructor. I've tried looking it up but the examples shown don't match with what I'm trying to write.
public class LinkedListOfInts {
Node head;
private class Node {
int value;
Node nextNode;
public Node(int value, Node nextNode) {
this.value = value;
this.nextNode = nextNode;
}
}
public LinkedListOfInts() {
}
public LinkedListOfInts(LinkedListOfInts other) {
}
public void addToFront(int x) {
head = new Node(x, head);
}
public String toString() {
String result = " ";
for (Node ptr = head; ptr != null; ptr = ptr.nextNode)
result += ptr.value + " ";
return result;
}
public static void main(String[] args) {
LinkedListOfInts list = new LinkedListOfInts();
for (int i = 0; i < 15; i++)
list.addToFront(i);
System.out.println(list);
}
}
You can iterate over the nodes of the other list and sequentially create new tail nodes based on their values.
public LinkedListOfInts(LinkedListOfInts other) {
Node tail = null;
for(Node n = other.head; n != null; n = n.nextNode){
if(tail == null) this.head = tail = new Node(n.value, null);
else {
tail.nextNode = new Node(n.value, null);
tail = tail.nextNode;
}
}
}
// ...
public static void main(String[] args) {
LinkedListOfInts list = new LinkedListOfInts();
for (int i = 0; i < 15; i++)
list.addToFront(i);
LinkedListOfInts copy = new LinkedListOfInts(list);
System.out.println(list);
System.out.println(copy);
}
So I am having trouble trying to build a linked list from a method that has two integer parameters n and m. Parameter n is the length of nodes of the linked list, and m is the parameter that contains random integers from 0 to m-1 inside the list of nodes. I am required to build this linked list from a predefined Node class that cannot be changed, and to return the reference to the first element from the linked list. I don't know how to traverse the linked list in the while loop.
Node class
public class iNode{
public int item;
public iNode next;
public iNode(int i, iNode n){
item = i;
next = n;
}
public iNode(int i){
item = i;
next = null;
}
Build the linked list method
public static iNode list(int n, int m){
iNode first;
iNode newNode;
iNode last;
first = null;
while ( )
{
newNode = new iNode(m, first.next);
if (m > 0){
newNode.item = m-1;
}
newNode.next = null;
if (first == null)
{
first = newNode;
last = newNode;
}
else
{
last.next = newNode;
last = newNode;
}
}
return first;
}
You are overcomplicating it. Just go from the end of the list and add nodes with the link to the previous one. In the end just return the last created node. Also, you are not adding random int from the range 0..m-1. Here it is:
public static void main(String[] args) {
iNode res = list(5, 10);
while(res != null){
System.out.println(res.item);
res = res.next;
}
}
public static iNode list(int n, int m) {
iNode previous;
iNode current;
int i = 0;
previous = null;
while (i < n) {
current = new iNode(ThreadLocalRandom.current().nextInt(0, m), previous);
previous = current;
i++;
}
return previous;
}
Output:
2
5
7
8
9
P.S. Please follow java code convention. Class names should start with capital letter - iNode
Given singly Linked List: 1 -> 2 -> 3 -> 4 -> 5 -> null
Modify middle element as doubly Linked List Node
here middle element is 3
3 -> next should point to 4
3 -> prev should point to 1
Can any one suggest how can it be done ? interviewer gave me hint use interface. but I couldn't figure it out how.
I have to iterate over this linked list and print all the node and when it reaches to the middle, print where next and prev is pointing to, then print till the end of the list.
Expected output : 1, 2, Middle: 3, Prev: 1, Next: 4, 5
I'm facing problem in adding the middle node.
So, this "works", but if this is expected to be answered on an interview, it is way too much work.
LinkedList
public class LinkedList {
public interface Linkable<V, L extends Linkable> {
V getValue();
L getNext();
void setNext(L link);
}
public static class Node implements Linkable<Integer, Linkable> {
int value;
Linkable next;
Node(int value) {
this.value = value;
}
#Override
public Integer getValue() {
return value;
}
#Override
public Linkable getNext() {
return next;
}
#Override
public void setNext(Linkable link) {
this.next = link;
}
}
private Linkable head;
public boolean isEmpty() {
return this.head == null;
}
public Linkable getHead() {
return head;
}
public void add(int v) {
Node next = new Node(v);
if (isEmpty()) {
this.head = next;
} else {
Linkable tmp = this.head;
while (tmp.getNext() != null) {
tmp = tmp.getNext();
}
tmp.setNext(next);
}
}
}
Interface
interface DoublyLinkable<V, L extends LinkedList.Linkable> extends LinkedList.Linkable<V,L> {
LinkedList.Linkable getPrev();
void setPrev(LinkedList.Linkable prev);
}
DoubleNode
public class DoubleNode extends LinkedList.Node implements DoublyLinkable<Integer, LinkedList.Linkable> {
LinkedList.Linkable prev;
public DoubleNode(int value) {
super(value);
}
#Override
public LinkedList.Linkable getPrev() {
return prev;
}
#Override
public void setPrev(LinkedList.Linkable prev) {
this.prev = prev;
}
}
Driver
Outputs
1, 2, Middle: 3, Prev: 1, Next: 4, 5
public class Driver {
public static LinkedList getList() {
LinkedList list = new LinkedList();
for (int i = 1; i <= 5; i++) {
list.add(i);
}
return list;
}
public static void main(String[] args) {
LinkedList list = getList();
LinkedList.Linkable head = list.getHead();
LinkedList.Linkable beforeMiddle = null;
LinkedList.Linkable middle = list.getHead();
LinkedList.Linkable end = list.getHead();
if (head != null) {
// find the middle of the list
while (true) {
if (end.getNext() == null || end.getNext().getNext() == null) break;
beforeMiddle = middle;
middle = middle.getNext();
end = end.getNext().getNext();
}
// Replace middle by reassigning the pointer to it
if (beforeMiddle != null) {
DoubleNode n = new DoubleNode((int) middle.getValue()); // same value
n.setPrev(list.getHead()); // point back to the front
n.setNext(middle.getNext()); // point forward to original value
beforeMiddle.setNext((DoublyLinkable) n);
middle = beforeMiddle.getNext();
}
// Build the "expected" output
StringBuilder sb = new StringBuilder();
final String DELIMITER = ", ";
head = list.getHead();
boolean atMiddle = false;
if (head != null) {
do {
if (head instanceof DoublyLinkable) {
atMiddle = true;
String out = String.format("Middle: %d, Prev: %d, ", (int) head.getValue(), (int) ((DoublyLinkable) head).getPrev().getValue());
sb.append(out);
} else {
if (atMiddle) {
sb.append("Next: ");
atMiddle = false;
}
sb.append(head.getValue()).append(DELIMITER);
}
head = head.getNext();
} while (head != null);
}
sb.setLength(sb.length() - DELIMITER.length());
System.out.println(sb.toString());
}
}
}
By definition, a single-linked list consists of single-linked nodes only, and a double-linked consists of double-linked nodes only. Otherwise. it is neither.
By definition the field prev of a double-linked list must point to the previous element.
Whatever you are supposed to build. It's something not well specified. So if you really were asked this in an interview (and did not misunderstand the question - maybe he wanted you to point out that ghis violates the interface?) this is a case for the code horror stories of http://thedailywtf.com/ - section "incompetent interviewers".
If you haven't, you'd better define a lenght() function so given one linked list you can know how many nodes does it have.
Thanks to the response of Cereal_Killer to the previous version of this answer, I noticed that the list is firstly a singly linked list, and you just have to make the middle node be linked both to the next node and to some previous node.
Now I guess that you have defined two structures (Struct, Class or whatever depending on the language you're using). So lets say you have Node_s defined as a node with only a next pointer, and Node_d with both a next and a prev pointer. (Node_d may inherite from Node_s so you just have to add the prev attribute in the child class). Knowing this, the code above should be doing what you need:
function do_it(my_LinkedList linkedList){
int i_middle;
int length = linkedList.length();
if ( (length รท 2 ) != 0 ) i_middle = length / 2;
else return -1;
Node_s aux = linkedList.first();
int index = 0;
Node_d middle= null;
while (aux != null) {
if (index == i_middle - 1){ //now aux is the middle's previous node
middle.data = aux.next.data; //aux.next is the middle singly node, we assignate the data to the new double linked node
middle.prev = aux; //as we said, aux is the prev to the middle
midle.next = aux.next.next; //so aux.next.next is the next to the middle
print(what you need to print);
}else {
print("Node " + index " next: "+ aux.next);
}//end if
index++;
aux = aux.next;
} //end while
}//end function
This previous code should be doing what you need. I wrote the answer in some kind of pseudo-java code so if you're not familiar with Java or don't understand what my pseudo-code does, please let me know. Anyway, the idea of my code may present some troubles depending on the language you're working with, so you'll have to adapt it.
Note that at the end of the execution of this program, your data structure won't be a singly linked list, and neither a double one, since you'll have linkedList.length() - 1 nodes linked in a signly way but the middle one will have two links.
Hope this helps.
I am creating a program that will read in a file, organize all of the words in lexicographic order, and output the word, how many times it appears in the document, and on what lines it appears. I have implemented this code in four different class files. However, I am having trouble linking the words to the linked list that will show the line numbers that the linked list arrives in. I am supposed to use the nodes of front and rear to traverse the list and am unsure how to go about iterating through this list and printing out each word.
here is the code form the class that take strings and make a linked list:
private class Node
implements Entry<String, IntQueue> {
String key;
IntQueue queue = new IntQueue();
Node link;
Node(String keyword, Node newlink) {
key = keyword;
link = newlink;
}
public String getKey() {
return key;
}
public IntQueue getValue() {
return queue;
}
public IntQueue setValue(IntQueue queue) {
throw new UnsupportedOperationException();
}
}
private Node head = new Node("", null);
public ListMap() {
// Not needed, since head defaults to null anyway.
}
public void insert(String key, int linenr) {
misc.trace("insert", key, linenr);
Node prevcursor = head;
Node cursor = head.link;
boolean write = false;
while (cursor != null) {
if (key.compareTo(cursor.getKey()) < 0) {
prevcursor.link = new Node(key, prevcursor.link);
prevcursor.link.getValue().insert(linenr);
write = true;
break;
}
if (key.compareTo(cursor.getKey()) == 0) {
cursor.queue.insert(linenr);
write = true;
break;
}
prevcursor = prevcursor.link;
cursor = cursor.link;
}
if (!write) {
prevcursor.link = new Node(key, prevcursor.link);
prevcursor.link.getValue().insert(linenr);
}
}
and here is the code that acually makes the int linked list:
class IntQueue
implements Iterable<Integer> {
private class node {
int linenr;
node link;
node(int number, node newlink) {
linenr = number;
link = newlink;
}
}
private int count = 0;
private node rear = null;
private node front = new node(0, null);
private int linenumb = 0;
private int count = 0;
private node rear = null;
private node front = null;
private int linenumb= 0;
public void insert (int number) {
++count;
misc.trace (count);
if(front=null){
node temp = new node(number,rear.link);
front = temp;
rear = temp;
}else{
if(linenumb != number ){
rear.link= new node(number,null);
}
}
linenumb = number;
rear = rear.link;
}
the big problem is the insert function in the second class. I can't understand how to link front and rear and to consistently add a new node every time the function is called in a way that can be called later
If your first issue is how to write the insert method for IntQueue then here are some suggestions. I'm assuming you don't want the code written as this looks like it's likely to be an assignment.
You are creating a new node as the front when the list is constructed. This is likely to be a mistake. The list is initially empty which is generally represented as front and rear being null.
The first thing to do in insert is to check if front is null. If it is you just set front and rear to a new node.
After that you know that rear will point to the most recently inserted node so you only need to check the new int to insert against rear.lineNumber.
Assuming you need a new node, create it, make rear.link point to it and then make rear point to it.
You're done.
As your assignment is a linked list with each node including a linked list I would expect your classes to be defined something like:
class WordList {
private class Node {
private String word;
private int count;
private LineNumberList lineNumbers;
private Node next;
}
private Node head;
private Node tail;
public addWord(String word, int lineNumber) {
...
}
}
class LineNumberList {
private class Node {
private int lineNumber;
private Node next;
}
private Node head;
private Node tail;
public addLineNumber(int lineNumber) {
...
}
}
Both addWord and addLineNumber should follow the same pattern as my algorithm above. However addWord will need to start by looking for the word and inserting it with a count of 1 if it's not present or incrementing the count if it is.