Smoothsort

Smoothsort is an $$O(n \log n)$$ algorithm, although it is adaptive with a best case of $$O(n)$$. It is not stable, and uses $$O(\log n)$$ memory.

Algorithm
Note: if you haven't read Heapsort, read it now. it provides the concepts for Smoothsort.

Leonardo Heaps and Trees
Leonardo heaps (as opposed to regular heaps) are based on the concept of Leonardo numbers. A Leonardo number $$L(n)$$ is defined as follows: $$L(1)$$ and $$L(0)$$ are 1. Otherwise, $$L(n)$$ = $$L(n - 2) + L(n - 1) + 1$$.

A Leonardo tree is defined similarly: A tree of order 0 or 1 are single nodes. Otherwise, they are a node with the Leonardo tree of the orders n - 1 and n - 2 as children. Leonardo trees must follow the heap property: that is, each node must be larger than its children.



Leonardo heaps are a forest of Leonardo trees arranged in such a way that the orders of the trees are sorted in descending order (no duplicate orders), and the roots of the trees are sorted in ascending order (that is, the tree with the largest root must be at the end). Now this structure allows us to efficiently remove the maximum (we can just crack the leftmost heap in two).

Insertion
To insert an item into a Leonardo heap, first check if the last two trees (the ones with the smallest orders) have sizes corresponding to the numbers $$L(n - 1)$$ and $$L(n - 2)$$. if so, simply make both trees the children of the new item. If not, check the order of the last tree. if it is 1, insert the item as a tree of order 0. otherwise, insert the item as a tree of order 1.

Now, to validate the property that the roots must be sorted, we insertion-sort the new root to its correct place, but with the added rule that the root should only be swapped with the previous one if the previous root is larger than both the root's children. Finally we do a regular sink operation in whichever tree the new root ended up in.

If the item to be inserted is the maximum element, the root will not be inserted and will automatically be a valid parent of any children. This allows heap insertion to be $$O(1)$$ in the best case.

Deletion
To delete the maximum from a Leonardo heap, look at the last tree. its root is guaranteed to be the maximum, and if it is only order 0 or 1, we can simply remove the tree. otherwise, we remove the root, cracking the heap in two, and apply the modified insertion sort described in Heap Insertion on the left and right children.

Like insertion, the best case for deletion is $$O(1)$$, either when the item to be deleted is the root of an order 0 ar 1 tree, or if its children are already in sorted order.

Implicit representation
To represent Leonardo heaps implicitly, we encode them in postorder, with each tree appended to the previous. Normally this would require $$O(\log n)$$ space to store the tree sizes, but with some bitwise manipulation it can be done in $$O(1)$$ space (although theoretically the algorithm would fail using this approach on huge array sizes).

Smoothsort is just Heapsort with Leonardo heaps substituted in, and as the operations on a Leonardo heap are $$O(1)$$ in the best case, Smoothsort is $$O(n)$$ time in the best case (an already sorted array).