I wanted to make a generic method for appending a copy of two linked list together and putting it in another linked list. list a and list b in list c.
here is the code that I have so far.
public static LinkedSequence<?> concatenaton(LinkedSequence<?> s1, LinkedSequence<?> s2) throws java.lang.NullPointerException
{
// Create a new sequence that contains all the elements from one sequence followed by another.
LinkedSequence<?> concat = new LinkedSequence();
if(s1 == null || s2 == null) {
return null;
}
else {
LinkedSequence h1;
LinkedSequence h2;
h1 = s1.clone();
h2 = s2.clone();
concat.addAll(h1);
concat.addAll(h2);
}
return concat;
}
public LinkedSequence<T> clone() {
// Generate a copy of this sequence.
LinkedSequence<T> copy = new LinkedSequence<T>();
//Node<T> newNode = new Node<T>(element);
Node<T> curr = first;
if(getCurrent() == null) {
return null;
} else {
while(curr != null) { //iterate through current list
copy.addLast(curr.getValue());
curr = curr.getLink();
}
}
return copy;
}
public void addLast(T element) {
Node<T> newNode = new Node<T>(element);
if (isCurrent() == false) {
current = newNode;
first = newNode;
last = newNode;
}
else {
//Node newNode = new Node(element);
last.setLink(newNode);
last = newNode;
}
}
the clone copies the whole list in a new list.
I keep getting an error saying that I make a generic type in a static type.
One thing is for sure... you need to use a type-parameter in your concat static method to impose the constraint that both input sequences have the same element type like so:
public static <E> LinkedSequence<E> concat(LinkedSequence<E> s1, LinkedSequence<E> s2) {
if(s1 == null || s2 == null) {
return null;
}
LinkedSequence<E> concat = new LinkedSequence<>();
concat.addAll(s1);
concat.addAll(s2);
return concat;
}
I took the liberty of edit the code a bit removing what seem to be redundant or inefficient.
You can make it a bit more general and accept inputs that contains type that are subclasses of the return type:
public static <E> LinkedSequence<E> concat(LinkedSequence<? extends E> s1, LinkedSequence<? extends E> s2) { ... }
You probably will need to change the addAll definition to accept ? extends E rather than E typed input collections.
Related
I'm having trouble writing a method that appends all elements in a method's parameter list to the end of another list. The method is supposed to return true if the list was changed, and false otherwise.
For example, if the original list was 1->6->5, and the other list is 3->8->2. After the call, the list is now 1->6->5->3->8->2.
I'm having trouble with the Boolean return statements as I am confused how they link into the logic of the list. I also don't know how far the pointers need to move in order to append the lists. The whole thing can be done in one loop but I don't know how.
public boolean appendList(DynamicList othrList) {
for (DynamicNode tmp = head; tmp != null; tmp.getNext()) {
if(tmp == null) {
DynamicNode ex = otherList.getList;
tmp.setNext(ex);
}
return true;
}
return false;
}
Full code:
public class DynamicNode {
private Object info; // the data in the node
private DynamicNode next; // refers to the next node on the list
public DynamicNode(Object x, DynamicNode n) {
info = x;
next = n;
}
public Object getInfo() { return info; }
public DynamicNode getNext() { return next; }
public void setInfo(Object x) { info = x; }
public void setNext(DynamicNode n) { next = n; }
public String toString() { return info.toString(); }
}
class DynamicList {
private DynamicNode head;
public DynamicList() { head = null; }
public DynamicList(DynamicNode head) { this.head = head; }
public boolean isEmpty() { return head == null; }
public DynamicNode getList() { return head; }
// The problem
public boolean appendList(DynamicList othrList) {
for (DynamicNode tmp = head; tmp != null; tmp.getNext()) {
if(tmp == null) {
DynamicNode ex = otherList.getList;
tmp.setNext(ex);
}
return true;
}
return false;
}
}
For the code in question (with comments in the code holding additional explanation).
This does fulfill the requirement: "if the original list was 1->6->5, and the other list is 3->8->2. After the call, the list is now 1->6->5->3->8->2."
It appends the elements(nodes) so after appending both list share the same nodes. Which should be okay. However this implies that if a node in "othrlist" changes after appending, it will also change in the list. Often this is the expected behavior.
So it is "shallow" and does not create any unessary (deep-)copies of elements.
To sum up this behaves the way, the aproach the op choose in his method does: One(!) loop, only appending and not duplicating.
public boolean appendList(DynamicList othrList) {
DynamicNode tmp = head;
if(tmp == null) { //special case empty list
head = othrList.getList();
return null != head; //early exit, list changed if head is no longer null.
}
while (tmp.getNext() != null) tmp = tmp.getNext(); //search for the last element
tmp.setNext(othrList.getList()); //link last element to head of other.
return null != tmp.getNext(); //list changed if tmp.next is no longer null(as it was before).
}
I have to write a duplicate function that duplicates every element of a linked list and returns a linked list such that if L = [2,3,4] then duplicate(L) = [2,2,3,3,4,4]. I have to do this recursively. I realize that below is not the correct solution, but I got confused. =(
public class MyList {
int value;
MyList next;
public static MyList duplicate(MyList L){
if(L.next == null){
L.next.value = L.value;
L.next.next = null;
} else {
MyList temp = L.next;
L.next.value = L.value;
L.next.next = temp;
duplicate(L.next);
}
return L;
}
}
First, check that L isn't an empty list (null). If it contains a value, return a new list that has that value repeated twice, followed by duplicating the rest of the list.
By giving MyList a constructor, this is more readable.
public class MyList {
int value;
MyList next;
public MyList(int value, MyList next) {
this.value = value;
this.next = next;
}
public static MyList duplicate(MyList list) {
if (list == null) {
return null;
} else {
return new MyList(list.value,
new MyList(list.value,
duplicate(list.next)));
}
}
}
You currently add an item and then call the recursion on it, ending at endlessly adding items.
You either need to at elements behind your recursion when processing in a forward-direction, or after the recursion when processing backwards.
Let's create a backwards-direction version. We first recursively walk to the end of the list and then resolve the recursion backwards, adding items after our current element each time.
public <E> void duplicateEntries(MyLinkedList<E> list) {
// Do nothing if list is empty
if (list.size() != 0) {
// Call the recursive method on the head node
duplicateEntriesHelper(list.head);
}
}
public <E> void duplicateEntriesHelper(Node<E> node) {
// Walk to the end of the list
if (node.next != null) {
duplicateEntriesHelper(node.next);
}
// Resolve recursion, duplicate current
// entry by inserting it after the current element
Node<E> duplicatedEntry = new Node<>();
duplicatedEntry.data = node.data;
// Insert element after current node
duplicatedEntry.next = node.next;
node.next = duplicatedEntry;
}
The classes I used should look similar to:
public class MyLinkedList<E> {
public Node<E> head = null;
#Override
public String toString() {
// Build something like "MyLinkedList[2, 3, 4]"
StringBuilder sb = new StringBuilder();
sb.append("MyLinkedList[");
StringJoiner sj = new StringJoiner(",");
Node<E> node = head;
while (node != null) {
sj.add(node);
node = node.next;
}
sb.append(sj);
sb.append("]");
return sb.toString();
}
}
public class Node<E> {
public Node next = null;
public E data = null;
#Override
public String toString() {
return E;
}
}
And here is the demo:
public static void main(String[] args) {
// Setup the list
MyLinkedList<Integer> list = new MyLinkedList<>();
Node<Integer> first = new Node<>();
first.data = 2;
Node<Integer> second = new Node<>();
second.data = 3;
Node<Integer> third = new Node<>();
third.data = 4;
list.head = data;
first.next = second;
second.next = third;
// Demonstrate the method
System.out.println("Before: " + list);
duplicateEntries(list);
System.out.println("After: " + list);
}
Of course you can add additional methods and functionality to them. For example using some constructors or getter/setter methods.
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 need help with a Circular Doubly Linked List in Java.
This is my code (originally coded by "sanfoundry"; it uses interfaces):
LinkedList.java:
public class LinkedList<T extends Comparable<T>> implements
ILinkedList<T> {
private ILinkedListNode<T> head;
private ILinkedListNode<T> end;
private int size;
public LinkedList() {
head = null;
end = null;
head = null;
size = 0;
}
#Override
public void append(T element) {
ILinkedListNode<T> tempNode = new LinkedListNode(element, null, null);
if (head == null) {
head = tempNode;
end = head;
} else {
tempNode.setPrev(end);
tempNode.setNext(tempNode);
end = tempNode;
}
size++;
}
// should return element at position "index"
#Override
public T get(int index) {
return null;
}
#Override
public int size() {
return size;
}
#Override
public ILinkedListNode<T> getHead() {
return head;
}
}
Now I need help to get it working. Did I do something wrong and what do I have to code in method "public T get (int index)"? Sorry, but I'm a Java noob :(
EDIT: Is this a possible solution?
public T get(int index) {
T element = null;
if (index == 0) {
element = head.getElement();
} else if (index == size()-1) {
element = head.getPrev().getElement(); // end.getElement() also possible
} else {
ILinkedListNode<T> temp = head;
for (int i = 0; i < index; i++) {
temp = temp.getNext();
}
element = temp.getElement();
}
return element;
}
You should traverse the LinkedList, keeping track of your current position as you go. When your current position is equal to the index passed in, then you can return the T from that node.
Read about traversing a linked list here.
Try making some test cases. Ideally you'll want to use a real test framework but using a normal main method could work. For example:
public static void main(String[] args) {
ILinkedList<String> a = new LinkedList<String>();
System.out.println(a.size()); // 0
System.out.println(a.getHead()); // null
a.append("foo");
System.out.println(a.size()); // 1
System.out.println(a.get(0)); // "foo"
System.out.println(a.get(1)); // decide yourself what this should result in
a.append("bar");
System.out.println(a.size()); // 2
System.out.println(a.get(0)); // "foo"
System.out.println(a.get(1)); // "bar"
a.append("baz");
System.out.println(a.size()); // 3
System.out.println(a.get(0)); // "foo"
System.out.println(a.get(1)); // "bar"
System.out.println(a.get(2)); // "baz"
}
Expand the test as necessary. See if the code returns what you expect it to, or if the code never returns, or throws an exception, etc.... The easiest way to check whether your code is running properly is, after all, to actually run it.
Hint: the code, as of this writing, has some errors.
Also, if the code can run as expected, consider:
Traversing the nodes backward if it's faster than forward.
Using a recursion instead of iteration.
I've been working through some standard coding interview questions from a book I recently bought, and I came across the following question and answer:
Implement an algorithm to find the nth to last element in a linked list.
Here's the provided answer:
public static LinkedListNode findNtoLast(LinkedListNode head, int n) { //changing LinkedListNode to ListNode<String>
if(head == null || n < 1) {
return null;
}
LinkedListNode p1 = head;
LinkedListNode p2 = head;
for(int j = 0; j < n-1; ++j) {
if(p2 == null) {
return null;
}
p2 = p2.next;
}
if(p2 == null) {
return null;
}
while(p2.next != null) {
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
I understand the algorithm, how it works, and why the book lists this as its answer, but I'm confused about how to access the LinkedListNodes to send as an argument to the method. I know that I'd have to create a LinkedListNode class (since Java doesn't already have one), but I can't seem to figure out how to do that. It's frustrating because I feel like I should know how to do this. Here's something that I've been working on. I'd greatly appreciate any clarification. You can expand/comment on my code or offer your own alternatives. Thanks.
class ListNode<E> {
ListNode<E> next;
E data;
public ListNode(E value) {
data = value;
next = null;
}
public ListNode(E value, ListNode<E> n) {
data = value;
next = n;
}
public void setNext(ListNode<E> n) {
next = n;
}
}
public class MyLinkedList<E> extends LinkedList {
LinkedList<ListNode<E>> list;
ListNode<E> head;
ListNode<E> tail;
ListNode<E> current;
ListNode<E> prev;
public MyLinkedList() {
list = null;
head = null;
tail = null;
current = null;
prev = null;
}
public MyLinkedList(LinkedList<E> paramList) {
list = (LinkedList<ListNode<E>>) paramList; //or maybe create a loop assigning each ListNode a value and next ptr
head = list.getFirst();
tail = list.getLast(); //will need to update tail every time add new node
current = null;
prev = null;
}
public void addNode(E value) {
super.add(value);
//ListNode<E> temp = tail;
current = new ListNode<E>(value);
tail.setNext(current);
tail = current;
}
public LinkedList<ListNode<E>> getList() {
return list;
}
public ListNode<E> getHead() {
return head;
}
public ListNode<E> getTail() {
return tail;
}
public ListNode<E> getCurrent() {
return current;
}
public ListNode<E> getPrev() {
return prev;
}
}
How can the LinkedListNode head from a LinkedList?
Update: I think part of my confusion comes from what to put in the main method. Do I need to create a LinkedList of ListNode? If I do that, how would I connect the ListNodes to each other? How would I connect them without using a LinkedList collection object? If someone could show me how they would code the main method, I think that would put things into enough perspective for me to solve my issues. Here's my latest attempt at the main method:
public static void main(String args[]) {
LinkedList<ListNode<String>> list = new LinkedList<ListNode<String>>();
//MyLinkedList<ListNode<String>> list = new MyLinkedList(linkedList);
list.add(new ListNode<String>("Jeff"));
list.add(new ListNode<String>("Brian"));
list.add(new ListNode<String>("Negin"));
list.add(new ListNode<String>("Alex"));
list.add(new ListNode<String>("Alaina"));
int n = 3;
//ListIterator<String> itr1 = list.listIterator();
//ListIterator<String> itr2 = list.listIterator();
LinkedListNode<String> head = new LinkedListNode(list.getFirst(), null);
//String result = findNtoLast(itr1, itr2, n);
//System.out.println("The " + n + "th to the last value: " + result);
//LinkedListNode<String> nth = findNtoLast(list.getFirst(), n);
ListNode<String> nth = findNtoLast(list.getFirst(), n);
System.out.println("The " + n + "th to the last value: " + nth);
}
In an attempt to connect the nodes without using a custom linked list class, I have edited my ListNode class to the following:
class ListNode<E> {
ListNode<E> next;
ListNode<E> prev; //only used for linking nodes in singly linked list
ListNode<E> current; //also only used for linking nodes in singly linked list
E data;
private static int size = 0;
public ListNode() {
data = null;
next = null;
current = null;
if(size > 0) { //changed from prev != null because no code to make prev not null
prev.setNext(this);
}
size++;
}
public ListNode(E value) {
data = value;
next = null;
current = this;
System.out.println("current is " + current);
if(size > 0) {
prev.setNext(current);//this line causing npe
}
else
{
prev = current;
System.out.println("prev now set to " + prev);
}
size++;
System.out.println("after constructor, size is " + size);
}
public ListNode(E value, ListNode<E> n) {
data = value;
next = n;
current = this;
if(size > 0) {
prev.setNext(this);
}
size++;
}
public void setNext(ListNode<E> n) {
next = n;
}
}
As is right now, the program will run until it reaches prev.setNext(current); in the single argument constructor for ListNode. Neither current nor prev are null at the time this line is reached. Any advice would be greatly appreciated. Thanks.
You don't actually need a separate LinkedList class; the ListNode class is a linked list. Or, to state it differently, a reference to the head of the list is a reference to the list.
The use of head, tail, current, prev in the sample code you posted has come from a double-linked list which is a data type that has links in both directions. This is more efficient for certain types of applications (such as finding the nth last item).
So I would recommend renaming your ListNode class to LinkedList and renaming next to tail.
To add a new item to the list you need a method that creates a new list with the new item at it's head. Here is an example:
class LinkedList<E> {
...
private LinkedList(E value, LinkedList<E> tail) {
this.data = value;
this.tail = tail;
}
public LinkedList<E> prependItem(E item) {
return new LinkedList(item, this);
}
}
Then to add a new item i to list you use list = list.prependItem(i);
If for some reason you need to always add the items to the end, then:
private LinkedList(E value) {
this.data = value;
this.tail = null;
}
public void appendItem(E item) {
LinkedList<E> list = this;
while (list.tail != null)
list = list.tail;
list.tail = new LinkedList<>(item);
}
However this is obviously pretty inefficient for long lists. If you need to do this then either use a different data structure or just reverse the list when you have finished adding to it.
Incidentally, an interesting side effect of this is that a reference to any item in the list is a reference to a linked list. This makes recursion very easy. For example, here's a recursive solution for finding the length of a list:
public int getLength(LinkedList list) {
if (list == null) {
return 0;
} else {
return 1 + getLength(list.getTail());
}
}
And using this a simple (but very inefficient!) solution to the problem you provided - I've renamed the method to make its function more obvious:
public LinkedList getTailOfListOfLengthN(LinkedList list, int n) {
int length = getLength(list);
if (length < n) {
return null;
} else if (length == n) {
return list;
} else {
return getTailOfLengthN(list.getTail(), n);
}
}
And to reverse the list:
public LinkedList<E> reverse() {
if (tail == null) {
return this;
} else {
LinkedList<E> list = reverse(tail);
tail.tail = this;
tail = null;
return list;
}
}
As I hope you can see this makes the methods a lot more elegant than separating the node list classes.
Actually you have created a linked list with you class ListNode.
A linked list is made of a node and a reference to another linked list (see the recursion?).