I have an array of values which is almost, but not quite sorted, with a few values displaced (say, 50 in 100000). How to sort it most efficiently? (performance is absolutely
Implement what we called in school a Shell's sort. That's bubblesorting sub-arrays. A sub-array with step k is an array of elements with indicies 0, k, 2k, 3k...
If you choose k = 3i+1, and perform multiple bubble sorts, starting from higher i-s downto 0, the times will be smaller on nearly-sorted array.
Just to put it on the table, a well implemented bubble-sort would certainly be the simplest algorithm here. With a worst-case of O(n*m), m being the number of displacements. The m part depends heavily on the pattern of displacements, usually total complexity would be O(n).
There are many good algorithms for this.
Smoothsort is my personal favorite... I actually worked all the math out here if you're curious why it works so well.
A fairly good algorithm for already-sorted data is natural mergesort, which is a bottom-up version of mergesort that works by treating the input as a sequence of sorted subranges, then making multiple passes over the range merging adjacent sorted ranges. It runs in O(n) time if the data is already sorted (because it can detect that there's only one sorted range), and O(n lg n) in the worst case. This algorithm works quite well if the data is "block sorted"; that is, it consists of a lot of sorted blocks placed right next to one another.
Straight insertion sort definitely works well for mostly-sorted data, but can degenerate very badly on a lot of inputs. Some really good sorts (like introsort) actually use this property of insertion sort to do a "cleanup step" on the input.
As Botz3000 noted, you can't perform such an operation faster than O(N). The most basic element of any algorithm would be to find those entries in the array that are out of order. This requires O(N), even before you figure out what to do with them.
If indeed the number of "out-of-order" elements is orders of magnitude below the total number of elements, you could use the following algorithm (assuming linked list):