I need to implement two methods named MoveToFront and MoveToBack. These have to move the item to the front of the array and move the item to the back of the array. But the problem is that this has to be constant, meaning that the amount of items have no influence on the time of the methods.
I think this is impossible to do with an array in Java. So I have to use another data structure for it. I was thinking to implement it with a linkedList but this would only be constant if I had the index of the item.
In your question statement you say the problem is 'move to the front of the array'. If it really means array, then you're right, it's not possible, because moving the array content is at least O(n), where 'n' is the position of the element to be removed.
If it's not an array, and you're allowed to choose the data structure, then fundamentally a linked-list is what you need. How is the element to be moved identified? If by index, it's straightforward, as you observed. Otherwise, keep a separate Map to allow O(1) lookup of the index for any element - assuming elements are unique. Then it's a matter of
a. Look in map to get index
b. Remove index'ed entry from list
c. Replace entry in list at desired position
d. Fix up map entry
Related
I have found following question on www.javatpoint.com
If you were to use a List implementation,but not sure which one to, because the requirement is not yet clear. In this case which List implementation will you use ?
options:
1. ArrayList
2. LinkedList
Correct answer for this is ArrayList
But there is no explanation why, Please help me to uderstand
Simple Term
ArrayList : Iterating Over An ArrayList is faster than Linked List, Because All Elements Stored in Contiguous Memory Location. But Performing Operation Like Delete Will Reduce Performance Because Again Entire List Order Changes (Like if you delete element at position 3rd then all next elements location are currentLocation - 1).
LinkedList : Slower When Iteration Performed(As Compare To ArrayList). But Delete and Update Operation Becomes Faster Because If you delete any element at any position only previous and after element locations are changed(Not Entire List).
So When You Don't Have Clear Requirements Just Iteration Is Basic Need (And Array List Gives Best Performance).
One possible reason might be that elements in ArrayList consume less memory space than in LinkedList, because each element in LinkedList contains a value plus a pointer to the next element, while an element in ArrayList has only value
ArrayList stores elements in array in insert order. You can get value by its index in array.
LinkedList stores your elements in Node objects that references each other. Each Node references previous and next Node. You can get elements sequentially starting from both sides. You can also get elements by index but it's not as fast as in ArrayList. Use LinkedList when you need sequential access, like queue or stack data structure
From what I've read in the past: An ArrayList essentially acts as a better array, allowing for dynamic resizing. A LinkedList is a double linked list which causes it to have better performance on adding and removing items from the list, but getting and setting at arbitrary positions is slower than an ArrayList. So, the question is most likely assuming that, generally, a program will be getting and setting values more than it is adding and removing values, which is a fairly reasonable assumption, but the question in question is incorrect.
I think I am missing a very obvious point but could not find it in my Java textbook.
I understand that node storage does not necessarily have to be contiguous in memory for linked list. Does this also mean that a linked list is not indexable? If so, then the only way to find an item in a linked list is to traverse the list, right, whereas you can get from an array by index?
Why is accessing an item by index slower in a linked list than an array?
A linked list has a chain of entries. If you want to get (say) the element at position 42, the code has to:
get the entry for the first element (position 0)
follow the next link to the entry for position 1
follow the next link to the entry for position 2
and so on .... 42 times in total.
There is no short cut.
I am still not understanding why a linked list is not indexable ....
Now a LinkedList is indexable in the sense that there is a get(int) operation that works. It is just that indexing a LinkedList is inefficient. In general, it takes O(N) steps to perform a get(i) in a linked list of length N. By contrast with an array, or an ArrayList, you can retrieve any element of the data structure in one step. We say that the complexity is O(1).
Contrast this with Set objects in general, and HashSet in particular. The HashSet class is NOT indexable because there is no get(int) method to retrieve the set element at position i. Indeed, even the notion of "position i" in a set is meaningless. The ordering of the elements in a Set is unspecified and (for some Set implementations, like HashSet) it may be effectively indeterminate.
Some Linked list implementations provide a way to access to it's elements using index, but the fact is that if you want to get 10th element in linked list your compiler still has to go through all the sequence from 0 to 9 because the elements may be spread over the memory. On the other hand when you ask for 10th element in an array using index, compiler computes the exact position of 10th element and jumps directly to that element. Array and list have different purposes; if your algorithm requires go back and forward over your data structure, then it is much efficient to use array. If you need mostly add/remove operations, then it is efficient to use list
With a linked list you can add and remove elements at any time so index it has no sense. Imagine that you create an index that points at the third element of the list. After that, you insert a new element at the beginning of the list. What value should return the index?
However it could be possible for example create an index at the middle of the list and use it only if you add o remove elements in the last half of the list.
#paxdiablo explains it very well here Is there a known implementation of an indexed linked list?
In the Collection framework tutorials for the List interface, there is an interesting quote regarding performance of removal of elements from a List implementation:
For many common List implementations, such as ArrayList, the performance of removing elements from the end of the list is substantially better than that of removing elements from the beginning.
The tutorials do not go further into explaining this and I am trying to understand exactly why it might be so.
Considering an ArrayList<Integer> list as below:
In the first scenario, if we remove the last 4 elements from the end of the list, then the values of these are set to null (or equivalent). My theory is that, when a copy operation is necessary, only the elements that are not null will be copied.
In the second scenario, if we remove the first 4 elements, they would be set to null again and again only non-null elements would be copied.
So from this point of view, the performances appear to be around the same. Is there another reason why the operation is faster if performed from the end?
On the other hand, for LinkedList, the inverse appears to be true; removal from the beginning is faster, whereas removal from the end requires an almost full traversal unless a tail-pointer
is kept.
As per my understanding,
ArrayList is an array implementation of a list. So if you remove elements from the beginning of an array you need to move all the remaining elements to fill up the elements that you removed. So this is going to essentially be a O(n-1) operation.However this is not the case when you remove elements from end of the list. This will be O(1).
There is more to removing elements from the beginning of the list than just setting the elements to null. You also need to move the remaining elements to fill in the vacated locations.
It's possible to use a variable to keep track of the "beginning" of the list without moving elements, but then you will sacrifice memory efficiency because of the unused elements in the array.
In ArrayList<> removing from start is slow because entire array will have to be shifted since the add function add the elements at and if we left the start empty then we will be wasting the memory.
If we take into account big(O) notation removing from start is essentially linear time O(n) while deleting from end is constant time O(1).
While Code-Apprentice's answer is correct, I'd like to elaborate on how you can verify the behavior that every entry is moved to the left by making an index-based lookup, i.e., calling list.get(index).
add two entries
remove the first element
check the value of the first element: is it now null or the previously second element?
The code to verify:
List<String> list = new ArrayList<>();
list.add("0");
list.add("1");
list.remove(0);
String entry0 = list.get(0);
System.out.println(entry0);
You suspected that null would be printed, but "1" is printed.
This confirms that all the elements are shifted to the left.
NB. I used Strings to avoid the confusion caused by remove(int index) and remove(Object o).
I am working on an algorithm that will store a small list of objects as a sublist of a larger set of objects. the objects are inherently ordered, so an ordered list is required.
The most common operations performed will be, in order of frequency:
retrieving the nth element from the list (for some arbitrary n)
inserting a single to the beginning or end of the list
removing the first or last n elements from the list (for some
arbitrary n)
removing and inserting from the middle will never be done so there is no need to consider the efficiency of that.
My question is what implementation of List is most efficient for this use case in Java (i.e. LinkedList, ArrayList, Vector, etc)? Please defend your answer by explaining the implementation s of the different data structures so that I can make an informed decision.
Thanks.
NOTE
No, this is not a homework question. No, I do not have an army research assistants who can do the work for me.
Based on your first criteria (arbitrary access) you should use an ArrayList. ArrayLists (and arrays in general) provide lookup/retrieval in constant time. In contrast, it takes linear time to look up items in a LinkedList.
For ArrayLists, insertion or deletion at the end is free. It may also be with LinkedLists, but that would be an implementation-specific optimization (it's linear otherwise).
For ArrayLists, insertion or deletion at front requires linear time (with consistent reuse of space, these may become constant depending on implementation). LinkedList operations at front of list are constant.
The last two usage cases somewhat balance each other out, however your most common case definitely suggests array-based storage.
As far as basic implementation details:
ArrayLists are basically just sequential sections of memory. If you know where the beginning is, you can just do a single addition to find the location of any element. Operations at the front are expensive because elements may have to be shifted to make room.
LinkedLists are disjoint in memory and consist of nodes linked to each other (with a reference to the first node). To find the nth node, you have to start at the first node and follow links until you reach the desired node. Operations at the front just require creating a node and updating your start pointer.
I vote for double linked list. http://docs.oracle.com/javase/6/docs/api/java/util/Deque.html
Probably the best data structure for this purpose would be a deque implemented with a dynamic array, which is basically an ArrayList that starts adding elements to the middle of the internal array instead of the beginning. Unfortunately Java's ArrayDeque does not support looking up an nth element.
It is, however, pretty easy to implement one yourself (or lookup an existing implementation), and then all three of the described operations can be done in O(1).
YOu can do all of them with arrayList with minimal confusion if your not worried about efficiency.
i would uses some sort of a queue or stack if i am only inserting at the front or end. They have the least overhead. Or you could also use a linked list.
To remove N elements from the first or end i would use a linked list, you can just delete one node and the ones before or after it are gone. Ie if i delete the first 5 elements just delete the 5th element and the ones before it will disappear. Also if i delete the last 6 elements just delete the 6th to last one and the rest will disappear. And java will do the garbage collecting for you. This would be an order of (1) for this operation.
is this a homework question?
Definitely go for LinkedList. For both inserting a value at the beginning/end of the list and removing the first/last element in the list, it runs in O(1). This is because all that needs to be changed to carry out these operations is a couple of pointers, a minimally costly operation.
Although ArrayLists retrieve the nth element in O(1) while LinkedLists retrieve the nth element in O(n), ArrayLists run the danger of having to adjust their size when elements are inserted. What do you suppose happens when the memory allotted for the ArrayList is used up and you try to insert another element? Well what happens is the ArrayList duplicates itself then allocates more memory (amounting to twice as much as it had initially allocated), a very costly operation. LinkedLists don't have this problem since, again, all that is done is the addition of a pointer.
I don't know a whole lot about Java Vectors, but if they're anything like C++ vectors, then they're very similar to ArrayLists.
I hope this helps.
java.util.TreeMap of Long to Object, and use index of i+tm.firstKey()
Can any one tell me clearly why ?
Reading is simple in ArrayList,( we can access through its array index ), why not in linkedList
Inserting element in arrayList is tough i heard why ? easy in linkedList why ?
Deleting element in arraylist is tough why ? easy in linkedList why ?
I know some thing about arrays, but what going in linkedXXX
Thank you.
In an ArrayList, you keep an array of references in memory, that is to say, you have a memory position. When you ask for the first element of an ArrayList, you just access the memory position. When you access the 10th element, you access the memory position + 10 times the size of a reference.
In an LinkedList, you have one element, which has a reference to the next. The next one references the next, and so on. As you can see, there is no direct way of accessing the 10th element in a LinkedList without going one by one getting the next element.
So, your questions:
Inserting element in arrayList is touch i heard why ? easy in linkedList why ?
There are two problems with inserting an element into an ArrayList:
When you put an element in position 3, you need to first move every element starting at position 3 and shift them right once (3 becomes 4, 4 becomes 5, etc...) so that 3 becomes empty and you can put in your new element
If the array that backs your ArrayList is already full, you need to create a new one! This is very costly, since you need to allocate the memory again, and then copy all elements to the new array, and destroy the old one.
In a Linkedlist, on the other hand, you go to element 1, which points to 2, and then go to 2. In 2, there's a reference to the old element 3, which you temporarily store elsewhere. You replace it with a reference to your new element, and in your new element, you make next point to the old 3. This is therefore way less costly.
Deleting element in arraylist is touch why ? easy in linkedList why ?
Similar reasons as inserting. In an ArrayList, you have to shift all the elements down again, in the LinkedList, once you are at element 2, you make its next point to 4, and voila, 3 is erased.
And for completeness
ArrayLists are great if you are going to access elements in a random order, but have the problems of adding and substracting. LinkedLists are great to add and remove, but getting an element that's not the first or last takes extra cost. So there's always a trade-off!
An ArrayList is backed by an array, which can't grow or shrink, nor can elements be inserted or removed. So insertion and removal are expensive operations, since a new array has to be created and the existing values copied from one array to the other. But an array can be accessed by index, so Random Access is much faster here.
A LinkedList consists of Node Objects that have pointers (yes, I know) to each other in one direction or both. It is very cheap to remove one of these nodes or insert a new one, but to get node nr. 12345, you have to start at the beginning and walk over 12344 nodes, which means random access is very expensive here. Note: A Java LinkedList is not only a List, btw, it also implements the Queue and Deque interfaces.
I think both are equally well suited for simple iteration, but the underlying mechanism is completely different.