I can not understand this.
When we call LinkedList.add(), we add an element to the end of the list, so if we want to mimic a stack with a linked list, we should call LinkedList.removeLast() for pop. I just can not understand why removeFirst() is used for pop?
Assuming my psychic abilities are correct, and you're using Java:
A list (which implements Deque) can be treated as either FILO (e.g. stack) or FIFO (e.g. queue), with seperate sets of methods for each.
In either case, you remove from the front.
When treating it as a stack you use push, to add to the front.
When treating it as a queue you use add to add to the end.
Related
LinkedList is a data structure, in which each element is coupled with a link to its next element.
So, in theory, this data structure is made for freely iterating through a list, in whichever direction, while performing whatever operations (except, maybe, deleting the element you're currently at).
However, in application, this isn't true. Returning an Iterator from a LinkedList is subject to the general Iterator rules (i.e. no modifying while iterating), and even creating a ListIterator, an improved Iterator, which allows modifying the next/previous element of the iterator, and let's you go forward/backward dynamically, still has severe limitations:
You can't delete elements from the beginning of the list if you're not currently there, and neither can you add elements to the end of the list, unless you're currently there.
So, is there a way to iterate freely through a LinkedList while performing whatever modifications to the list? And if not, why isn't there one? Shouldn't it be one of the main goals of this data structure to realize it?
The choice to make all Iterators failfast was a design decision, just that and nothing more.
Nothing stops you to take the code and starting from that, build a NotSoFailFastIterator for yourself if you think you can use it. However I think you'll quickly revert from using it once yoy see its behaviour and its results in usage scenarios where there's really lots of concurrent activity going on on the underlying List of your iterator.
This behavior is not specific to LinkedLists. When you iterate over a List (any List) with a ListIterator, you can only make structural changes (adding or removing elements) in the current position of the iterator. Otherwise, continuing to use the iterator after a structural change of the List may yield unexpected results.
For adding elements to the start or end of the LinkedList, you have addFirst and addLast methods. You don't have to iterate over the List in order to do that.
A ListIterator instance maintains a state that allows it to locate the next and previous elements as well as support other operations (remove the current element, add an element at the current position). If you make a structural change to a List not via the ListIterator, the state of the iterator may become invalid, leading to unexpected results. Therefore all structural changes must be made via the ListIterator.
I guess that the LinkedList class could supply an implementation of a more complex iterator that supports operations such as addFirst and addLast. I'm not sure how useful that would have been, and whether it would justify the added complexity.
If you want to iterate freely use array or list. Linked lists are meant to be traversed and access the data useful in dynamic allocation of the memory to the data.
When you have a linked list datastructure, you can add or remove at a particular node, when your cursor is pointing to the right node where you want to add or remove.
Inserts the specified element into the list (optional operation). The
element is inserted immediately before the element that would be
returned by next(), if any, and after the element that would be
returned by previous(), if any. The new element is inserted before
the implicit cursor: a subsequent call to next would be unaffected,
and a subsequent call to previous would return the new element. (This
call increases by one the value that would be returned by a call to
nextIndex or previousIndex.)
ListIterator
Instead if its a array structure, then you access by index , and it is possible to add or remove at a particular index limited , by the length of the array. ArrayList does that.
As we know in Java each class that implements Collection interface should implement Iterator<E> iterator() method.
Stack and Queue are parts of collection hierarchy and implement this method as well. So we can write something like this:
Stack stack = new Stack();
// Deque stack = new ArrayDeque<>();
stack.add( "1" );
stack.add( "2" );
stack.add( "3" );
Iterator i = stack.iterator();
while ( i.hasNext() ) {
Object o = i.next();
if ( o.equals( "2" ) ) {
i.remove();
}
}
My concerns here are:
Is it ok that we are able to delete elements from the middle of the stack/queue?
Is it ok that stack/queue should "show" only one element (last in stack and first in queue) but actually we are able to get all of them without calling "pop","enqueue" methods?
In the strictest sense, Stack and Queue should not allow iteration over it's element but the only reason this restriction exists is to justify the existence of these data structures. As per sgi
Stack does not allow iteration through its elements.
This restriction is the only reason for stack to exist at all. Note that any Front Insertion Sequence or Back Insertion Sequence can be used as a stack; in the case of vector, for example, the stack operations are the member functions back, push_back, and pop_back. The only reason to use the container adaptor stack instead is to make it clear that you are performing only stack operations, and no other operations.
While some implementations follow this, for example std::stack in C++ does not expose iterator, other implementation provide iterators as a feature. Stack in java is built on top of Vector which implements iterator. Queue is built on top of Collection which requires iterator to be implemented. To answer your questions
Is it ok that we are able to delete elements from the middle of the stack/queue?
Yes. The underlying implementation will make sure that your stack/queue is in a consistent state after the deletion.
Is it ok that stack/queue should "show" only one element (last in stack and first in queue) but actually we are able to get all of them without calling "pop","enqueue" methods?
Yes it's a feature of the underlying implementation.
Is it ok that we are able to delete elements from the middle of the
stack/queue?
Yes since stack/queue both will keep their contract even after deleting , after all the methods exposed by stack/queue manipulate the internal implementation which is used for the deletion
Is it ok that stack/queue should "show" only one element (last in
stack and first in queue) but actually we are able to get all of them
without calling "pop","enqueu" methods?
Yes you are not violating either contract since the remove is done throw iterator interface of the element not queue or stack
I am considering using a Java collection that would work best with random insertions. I will be inserting a lot and only read the collection once at the end.
My desired functionality is adding an element at a specified index, anywhere between <0, current_length>. Which collection would be the most efficient to use?
Useful link for your reference:
http://www.coderfriendly.com/wp-content/uploads/2009/05/java_collections_v2.pdf
Not entirely sure how you will be reading the information post input (and how important it is to you). Hashmap or ArrayList would make sense depending on what you are looking to do. Also not sure if you are looking for something thread safe or not.
Hope it helps.
The inefficiency of using List is endemic to the problem. Every time you add something, every subsequent element will have to be re-indexed - as the javadoc states:
Shifts the element currently at that position (if any) and any
subsequent elements to the right (adds one to their indices).
From your question/comments, it would appear that you have a bunch of Objects, and you're sorting them as you go. I'd suggest a more efficient solution to this problem would be to write a Comparator (or make your object implement Comparable), and then use Collections.sort(list, comparator) (or Collections.sort(list)).
You might suggest that your Objects are being sorted on the basis of other variables. In which case, you could create an extension of the Object, with those other variables as fields and extending Comparable, and with a method like getOriginal(). You add these wrapped objects to your list, sort, and then iterate through the list, adding the original objects (from getOriginal()) to a new list.
For info on the sorting algorithm of collections - see this SO question
I want to implement a blocking where I can add element any time, any way. But I must be able to access them sequentially.
For example, consider a queue of x elements where the elements 1,4,8,10 have been added. So 10 can be accessed, but until 9 is added and accessed, 8 cant be. In short, all the elements are interrelated.
Please let me know if java already has such type of collection implemented. So I can use it directly.
You're talking about either a stack or a queue, depending on if you want them to be FIFO or LIFO, combined with inserting the elements in numerical order in the first place - meaning you're sorting the elements upon insertion so they are always in the correct numerical order.
By sorting the elements by numerical order upon sort, it's guaranteed that they'll be in the order you expect when you remove them.
You can use Java's a LinkedList to both insert elements where you want them in the list, and also remove them either form the "back" or "front" of the list, as needed.
Finally, in order to ensure that you cannot remove an item unless it is the next in the sequence, you need to simply do a check on the value before removing it from the list to make sure that it was sequentially the next one after the last element removed. If it doesn't pass that criteria, either return "false" or some other value that indicates that nothing can be removed from the list at this time.
Also, check out this question: Creating a blocking Queue<T> in .NET? - it's not Java, but it's very similar, and may provide some insight.
Wrap Queue with logic that pushes items to it in order. Eg. create a class which implements Queue and BlockingQueue. Most methods (like get) delegates directly to something like an internal ArrayBlockingQueue, but "put" would put stuff onto the internal ArrayBlockingQueue in order. If put is called with an element that should not yet be accessible, you store it in another, intermediate, data structure.
Every time put is called with an element that is "next up", you push it to the queue, and then go through your intermediate data structure and add any elements to the queue that can now be added.
I need to create a FIFO queue. I was thinking in creating a LinkedList for that, because of it's native methods to remove and add. But my queue should have a fixed size, so how could I fix that size?
Thanks in advance!
The easiest thing would be use one of the implementations of java.util.Deque or java.util.Queue
You can wrap an instance of a LinkedList in your own class, and control the size (composition). The downside (or upside, based on your preference) of this is that you can control which methods to explose, in this case add and remove. Another alternative is to extend LinkedList and override add/remove while controlling the size.
If you must have a fixed size, then you ought to use an ArrayList (or just an array) to back the FIFO.... Just keep a variable representing the index of the head, and a variable representing the index of the tail and move them around as you push and pop.
However, if this isn't homework, you should probably just use one of the many available Collections classes. They do the job very well.