I have been stumped by this question in one of my tutorials:
Given a Circular linked list which has only a tail pointer, write a recursive method with the following header to print out the list recursively starting from the first element:
public void circularPrint()
I could easily do this question had it not stated to print out the list starting from the first element. But I am stumped because of the multiple restrictions that are enforced by this question. Could someone please advise me on how to solve this problem?
Thank you.
If it's circular linked list, that means that the last element (tail) has a field pointing to the first element. So at this moment you also have a head (so to speak).
You can do it for example this way:
Print the tail's next element (which is the 1-st element).
Assign the second element to the tail's next.
Repeat.
Is the list only one circle, like a circular buffer? Then you can print until the next pointer is the same as the reference to the list.
If the circles can be in to any previous element then you need to apply one of the Turtoise and hare algorithms.
It's quite easy with singly linked lists. Not so easy if you have like Scheme cons cells that can have structure in both pointers which would require quite a bit of backtracking and housekeeping.
As for you problem with the method signature I haven't heard of inner methods in Java so you'll need to define a helper. eg.
public void circularPrint()
{
circularPrintAux(this);
}
For turoise and hare it would be:
public void circularPrint()
{
if( this.next == this )
...
else
circularPrintAux(this, this.next);
}
You will need to pass in two parameters, the current element and the starting element. For your first call, these will be the same. Once you've printed the current element, recursively call on the next element in the list. Only do the recursive call if the next element != the starting element.
Related
I have this list : [5,3,5,5,3,7,7,5,3,2]
and I need to remove every time I have a sequence in the list which is the same as a queue given to me - for example the queue [exit-5,3-enter] my function returns
[5,3,5,7,7,2-->null] but I want it to be [5,7,7,2-->null].
I would also like to mention that when I am talking about a linked list I actually mean a list of nodes-
Node<Integer> lis
(it has a value and a pointer to the next node). I already did the function I mentioned but what I did doesn't work if the sequence appears at the start of the list-like Iv'e already mentioned because I don't know how to remove from the start of the list. I know how to remove a node I just reference to next Nodes and leave it with no reference but my function gets a copy of the main reference to the list
public static void removeAppear(Node<Integer> n,Queue<Integer> q){
so if I would just write :
n=n.getNext();
for example it won't actually delete the first node, and from the void main method I would still see the first node. If you need the function I did say so but I really just need to know how to delete a first node.Sorry if it's a basic question but i'm quite new to programming.
You can’t mutate a linked list to remove leading nodes, unless you stop thinking of your function as ‘changing the list’ and start thinking of it as ‘returning a new list which is different from the original’. Then it can return a reference to a node which was not originally the first node.
My book only mentions circular linked lists on one page and says that you can create them by making the head and tail of single or double linked lists linked to each other. But then the programming exercise says:
"A circular-linked list has no need of a head or tail. Instead, you need only a reference to a current node, which is the nextNode returned by the Iterator. Implement such a class. For a nonempty list, the Iterator.hasNext method will always return true."
I'm not really sure how I should approach this.
The exercise is worded in a way not to limit you in your implementation decision: rather than prescribing a particular solution, it lets you implement the list in a way that you find most convenient.
You do need to have a pointer into the list, but since the list is circular, it does not need to point anywhere in particular. Since it does not point to a head or a tail, you can call it next, and keep it pointing to any element that you find convenient:
After insertion, next could point to the element that you have just inserted
After deletion, next could point to the element after or before the deleted one
After a search, next could remain unchanged
In order to convert your single or double linked list to circular, u l link the head and tail.. now the list structure is circular.. so it is not necessary to have a head / tail. Bcoz all nodes are interlinked and so no pointer has next node as null.
And circular list is of 2 types.
Single circular list - has hasNext() method nly
Double circular list.- has hasNext() and hasPrev()
The above mentioned methods are the ways of traversing in the circular linked list.
Problem is I don't understand how to create a tree. I have gone through many code examples on trees but I don't even know how to work with/handle a node and hence I don't understand how the node class works(that was present in all the program examples ). When i try to use methods such as appendChild(as mentioned in java docs),I get an error,and I am asked to create one such appendChild method inside that node class within the main program. Couldn't understand why that happened.
I am given integer pairs((u,v) meaning there is an edge between u & v) of nodes and I also need to know if any Element-to-node conversion is required for using u and v(of type integer) as nodes.
Please bear with me since my basics are weak. Little explanation on how the entire thing works/functions would be very helpful.
Thank you.
EDIT 1: I went through the following links:(hardly found anything on just unordered trees) http://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/code/BST.java http://www.newthinktank.com/2013/03/binary-tree-in-java/ . Tried to modify these codes to meet my own purpose but failed.
I only got a blurry idea and that is not enough for implementation. I am trying to make a simple unordered tree,for which i am given u v pairs like:
(4,5) (5,7) (5,6). I just need to join (4<--5),(5<--7) and (5<--6). So how do I write a node class that only joins one node to the prev node? Besides,to do only this,do I need to bother myself with leftchild,rightchild? If not,how will I be able to traverse the tree and do similar operations such as height diameter calculation etc later?
Thank you for your patience.
Well Its not entirely clear whether you want an explanation on tree creation in general, on some tree implementation you have found, or you have a basic code already that you cannot get working. You might want to clarify that :).
Also tree creation in general:
Most explanation and implementation you will find might be "overly" elegant :). So try to imagine a simple linked list first. In that list you have nodes(the elements of the list). A node contains some valuable data and a reference to an other node object. A very simple tree is different only in that a node have more than one reference to other nodes. For example it has a Set of references, its "children".
Here is a VERY crude code only as an example for addChild() or appendChild in your case:
public class Node {
private String valueableData;
private Set<Node> children;
public Node(){
this.children=new HashSet<Node>();
}
public Node (String valueableData){
this.valueableData=valueableData;
this.children=new HashSet<Node>();
}
public void addChild(Node node){
children.add(node);
}
}
Now this implementation would be quite horrible (I even deleted the setter/getters), also it would be wise to keep the root nodes reference in some cases, and so on. But you might get the basic idea.
You might wanna create a cycle or recursion to go over the (u,v) integer pairs. You create the root node first then you just addChild() all the other nodes recursively, or create every node first then setChild() them according to your rules.
It looks to me that there is no way to insert an element somewhere in the middle of a Deque class in O(1) time. I want to maintain a reference to a particular node in the deque in say a hash table and if I need to remove this node, I just go to its prev and set the prev.next=this.next and similarly this.next.prev=prev and remove this current elem.
But if I have a deque as
Deque<String> myDeque = new ArrayDeque<String>();
or
Deque<String> myDeque = new LinkedList<String>();
none of these would provide this.
Is there an alternative to this? If I have to implement my own Doubly linked list, is there a way that I can do away by just extending what ArrayDeque already does so I don't have to rewrite the code for insert etc? ...well as far as i know...i don't think so : ( : (
This is not possible without writing your own Deque. However:
If I understand correctly you want O(1) removal and insertion at one specific point in an object that otherwise has the interface of a Deque? May I suggest that you use two Deques?
Insertion and removal are at first only in one of the Deques, untill you come across the node you want to save. At that point, depending on wether you insert this node at the front or at the back you don't do that, but insert the node in the empty Deque, and that empty Deque becomes the target for either all your insertions and removals at the front or the back from then on, and the other Deque only handles insertions and removals at the back or front.
This would scale maybe to a few key nodes (leading to [number of nodes]+1 Deques used), with only insertions/removals happening at the front of one Deque and at the back of one other Deque (all others are static). You would also have to introduce a fixed convention of wether the first or the last item in each Deque (except the first or the last Deque) is a "key" node.
Of course if you have random insertion and removal at many points the question becomes: Why do you insist on a Deque?
I wouldn't remove the node. Instead when you take it from the Deque I would check your collection of elements to be removed/ignored and then discard it if required.
Our homework assignment asks us to prove that the Java LinkedList implementation is doubly-linked and not singly-linked. However, list operations such as adding elements, removing elements, and looking elements up seem to have the same complexity for both implementations, so there doesn't seem to be a way to use a performance argument to demonstrate the doubly-linked nature of Java's LinkedList. Anyone know of a better way to illustrate the difference between the two?
Look at iterating in forward or backward direction, removing the "before-last" element, and such.
It's quite an easy proof -- you look at the source code and see that each node has a .previous pointer :)
http://www.docjar.com/html/api/java/util/LinkedList.java.html
Consider the following nodes, single and double.
class SingleLinkedNode {
E data;
SingleLinkedNode next;
}
class DoubleLinkedNode {
E data;
DoubleLinkedNode prev;
DoubleLinkedNode next;
}
If we want to remove from a DoubleLinkedList (assuming we have already FOUND the node, which is very different) what do we need to do?
Make the node before the deleted
one point to the one after.
Make the node after the deleted one point to the one before.
If we want to remove from a SingleLinkedList (assuming we have already FOUND the node, which is very different) what do we need to do?
Make the node before the deleted one point to the one after.
You'd think that means it's even faster in a single linked list than a double.
But, how are we doing to delete the node if we don't have a reference to the one before it? We only have a reference to the next. Wouldn't we have to do a whole other search on the list just to find prev? :-O
The Java List interface doesn't have a method which allows you to remove an item without searching through a linked list. It has remove(int index), which would have to scan the list to find the indexed entry, and it also has remove(Object o), which has to scan the list as well. Since a linked list implementation can save the necessary previous-item entry context while scanning, remove has equivalent complexity for singly- and doubly-linked lists. This state can be saved in an iterator, as well, so Iterator.remove() doesn't change this. So I don't think you can tell from remove performance.
My guess is that the "right" answer to this is to create several lists of different sizes and time the performance of .indexOf() and .lastIndexOf() when searching for the first or last object. Presuming that the implementation is doubly-linked and searches from the beginning of the list for .indexOf() and searches from the end for .lastIndexOf(), the performance will be length-dependent or length-independent.