Weave Merge sort

Weave Merge sort is a sorting algorithm, with $$O(n^2)$$ time complexity for all cases. The idea of the sorting algorithm is that since on shuffled data, Merge Sort has two sorted sublists to be merged, with its elements spread about evenly, from the lowest element of the whole list to the highest.

Algorithm
To weave two lists together, alternately interleave them, with the second list as the first element, e.g.  becomes. This algorithm is also called in-shuffle. The simplest way to do so is to move each elements from the second list, from left-to-right, to the appropriate place.

To sort using Weave Merge, recursively sort the left and right halves of the list. Then, the two halves are weaved. Insertion sort is finally used to sort the list.

Complexity
The weaving operation described above takes $$O(n^2)$$ time. Furthermore, in the worst case scenario where an already sorted list is weaved, Insertion sort takes $$O(n^2)$$ time to sort it again. Weave Merge has a similar runtime to that of a merge sort: $$T(n) = 2T(n/2) + O(n^2) + O(n^2)$$ which simplifies to $$O(n^2)$$ because of the master theorem.

On random inputs, Insertion sort is $$O(n^{3/2})$$ time due to the insertion costs being equal to a Shellsort using power-of-two gaps, where the latter's average runtime is computed. On more ideal inputs, Insertion sort gets closer to $$O(n)$$, but a modification of the weave process must be done in order to take advantage of it.

Improved Weave Merge
The weaving operation is decreased to $$O(n \log n)$$ using a recursive process.

Optimized Weave Merge sort
Optimized Weave Merge achieves the optimal weave time of $$O(n)$$ using one of two methods. Inserting is now modified to make $$O(n)$$ comparisons worst case similar to that of Merge sort.

Weave using bit reversal
On halves $$A$$ and $$B$$ of size $$2^k$$ where $$k$$ is an integer, it is possible to perform three bit reversal permutations to weave the two halves together in $$O(n)$$ data moves:


 * 1) Bit-reverse $$A$$ and $$B$$ separately
 * 2) Bit-reverse $$AB$$ together

As usual, if the halves aren't a power-of-two length, use rotations to tail recursively swap and weave power-of-two sized blocks from the two halves until both sequences are weaved entirely.

Bit reversal in O(n) time
While this method makes $$O(n)$$ swaps, the bit reversal also needs to be $$O(n)$$ time. In a naive implementation, it costs $$O(\log n)$$ to reverse the bits in an index. Doing so for each index results in a hidden $$O(n\log n)$$ time overhead from index calculations which is sub-optimal.

Another method is to pre-calculate the bit reversals once in $$O(n\log n)$$ and store them in a lookup table allowing $$O(1)$$ time index calculations thus $$O(n)$$ time bit reversal permutations. However, this method incurs an extra $$O(n)$$ space while all other methods are in-place.

The solution is to use the trailing zeroes of each index to calculate subsequent indices:

Since there are $$O(n)$$ trailing zeroes in a range of numbers $$1,2,3,4\dots n$$, the solution is $$O(n)$$ ($$O(1)$$ amortized per index).

This method, however, does not provide a general method for bit reversing in $$O(1)$$ time since each calculation relies on the result of the previous index.

Insertion comparison optimization
The fact that odd and even indices of a list are always sorted when woven, can be used to reduce the comparisons to $$O(n)$$ worst case. Furthermore, a flag can be used to make the algorithm stable. This is done as follows:


 * Compare and insert each time, starting from the first and second index.
 * When out of order, or the flag is enabled and elements are equal: insert the right into where the left element is located, and then move the right index forward by 2 steps, keeping the parity same.
 * Move the left index forward by 1 step, as after each comparison, these elements are considered merged as one. Repeat this process.
 * If the indices are equal after movement, move the right index forward by a step. The flag is negated.

If the index on right goes out of bounds, it means the odd or even indices of the list have been inserted. The algorithm can terminate early.

The following is an implementation in Java: