views:

74

answers:

2

I have a list that is frequently insertion sorted. Is there a good position (other than the end) for adding to this list to minimize the work that the insertion sort has to do?

+1  A: 

The best place to insert would be where the element belongs in the sorted list. This would be similar to preemptively insertion sorting.

Adrian Park
Preemptive insertion sorting!? What will they think of next?
Michael Dillon
A: 

Your question doesn't make sense. Either the list is insertion sorted (which means you can't append to the end by definition; the element will still end up in the place where it belongs. Otherwise, the list wouldn't be sorted).

If you have to add lots of elements, then the best solution is to clone the list, add all elements, sort the new list once and then replace the first list with the clone.

[EDIT] In reply to your comments: After doing a couple of appends, you must sort the list before you can do the next sorted insertion. So the question isn't how you can make the sorted insertion cheaper but the sort between appends and sorted insertions.

The answer is that most sorting algorithms do pretty good with partially sorted lists. The questions you need to ask are: What sorting algorithm is used, what properties does it have and, most importantly, why should you care.

The last question means that you should measure performance before you do any kind of optimization because you have a 90% chance that it will hurt more than it helps unless it's based on actual numbers.

Back to the sorting. Java uses a version of quicksort to sort collections. Quicksort will select a pivot element to partition the collection. This selection is crucial for the performance of the algorithm. For best performance, the pivot element should be as close to the element in the middle of the result as possible. Usually, quicksort uses an element from the middle of the current partition as a pivot element. Also, quicksort will start processing the list with the small indexes.

So adding the new elements at the end might not give you good performance. It won't affect the pivot element selection but quicksort will look at the new elements after it has checked all the sorted elements already. Adding the new elements in the middle will affect the pivot selection and we can't really tell whether that will have an influence on the performance or not. My instinctive guess is that the pivot element will be better if quicksort finds sorted elements in the middle of the partitions.

That leaves adding new elements at the beginning. This way, quicksort will usually find a perfect pivot element (since the middle of the list will be sorted) and it will pick up the new elements first. The drawback is that you must copy the whole array for every insert. There are two ways to avoid that: a) As I said elsewhere, todays PCs copy huge amounts of RAM in almost no time at all, so you can just ignore this small performance hit. b) You can use a second ArrayList, put all the new elements in it and then use addAll(). Java will do some optimizations internally for this case and just move the existing elements once.

[EDIT2] I completely misunderstood your question. For the algorithm insertion sort, the best place is probably somewhere in the middle. This should halve the chances that you have to move an element through the whole list. But since I'm not 100% sure, I suggest to create a couple of small tests to verify this.

Aaron Digulla
I said the list is *frequently* insertion sorted. It's just a regular list but i perform an insertion sort on it quite often.
RCIX
Then please elaborate. You must sort it after every group of appends before you try to insert; otherwise the insertion sort will break. So either there is a bug or your question should be "How do I add items in such a way that sorting before the next ordered insert will be as cheap as possible"?
Aaron Digulla
I sort before i do anything important to the list. I'm just asking; is there a single default place for inserting in a list that will minimize the amount of time on average my insertion sort has to work for to sort the new items?
RCIX
See my edits. Short answer: Insert them at the beginning.
Aaron Digulla
I use insertion sort.... http://www.sorting-algorithms.com/insertion-sort I use it for the case of "almost-sorted lists" because that's what i need highest performance in. As to why i care: when i say frequently sorted, i mean hundreds if not thousands of times per second, and any small bit will help.
RCIX
Ah ... sorry, misunderstanding. I was under the impression that you use a standard Java list which sorts when you call `add(element)`;
Aaron Digulla