Smooth Sort & Leonardo Heap
Smooth Sort & Leonardo Heap
Heapsort being the direct ancestor of smooth sort was slightly inefficient in managing large
data sets as it had the next, worst and the average case complexities of nlogn.
Smooth sort aims at attaining the worst case complexity of O(nlogn) but a best case complexity
of simply n which is a great deal!
Overview of Smooth Sort
Smooth sort has a very similar implementation as that of heap sort but instead of a binary heap
tree, we will use a forest of several binary max-heap trees.
This absurd data structure representing the forest is called a ‘Leonardo Heap’.
Leonardo Heaps
A leonardo heap represents a forest of balanced max/min heap trees where the number of
nodes in each heap is a ‘Leonardo Number’
Apart from this, the array representation of each heap is a bit different. Instead of the root
element being the leftmost element and it’s children being on the right side of it, leonardo
heaps contain the root element in the rightmost index and it’s children lie to the left side.
Leonardo Numbers
Leonardo Numbers are the numbers that belong to the leonardo series, a series very similar to
the fibonacci sequence!
L(1)=1;
L(n)=L(n-1)+L(n-2)+1;
1 1 3 5 9 15 25 . . .
Leonardo Numbers
2 really important lemmas which form the foundation of leonardo heaps are:
1) Any positive integer can be written as the sum of O(logn) distinct leonardo numbers thus
signifying that any binary tree of n numbers can be translated to a leonardo heap of k
different binary max heaps.
2) For any n, the number of binary trees needed to form the heap k is at most log n.
These lemmas are proven but are far beyond the reach of discussion for this particular topic.
Leonardo Heaps (contd.)
As discussed earlier, the number of heaps in the leonardo heap could be: 1 or 3 or 5 or 9 or 15
and so on.
1) Insertion
2) Deletion
Leonardo Heaps: Operations->Insertion
1) The number of elements in the 2 smallest leonardo trees after inserting the new element
will be a leonardo number
2) The number of elements in the 2 smallest leonardo trees after insertion of the new
element won't be a leonardo number.
Insertion: Step 1 -> Case 1
If it follows the first case, we merge the 2 smallest heaps with the new element as the root of
the new merged heap.
Insertion: Step 1 -> Case 2
If the circumstance follows the second case instead, we simply create a new singleton heap
with just the new element as the only 1 element in the heap.
Insertion: Step 2
For sorting the different leonardo trees/heaps, we practically use insertion sort in a much more
complex way (as we know that heaps can be represented as arrays).
The new element isn’t necessarily the largest element as we haven’t yet restored the property
of the max heap.
We also can’t just naively swap the root to its supposedly right position.
Insertion: Step 2 (contd.)
Thus, we apply insertion sort and swap only if the root is greater than the root of its preceding
tree and its sub tree's roots to ensure a ‘mostly heapified’ heap.
In the end we will end up with several heaps in the leonardo tree/forest where the heaps might
not be perfectly heapified but the maximum element of each heap will be on the top and will
be in ascending order as we move from left to right.
Now, we simply heapify the heaps to get the desired leonardo heap
Deletion
We consider 2 cases:
We simply remove the root of the rightmost heap as the resultant heap will still be a leonardo
heap.
Deletion: Case 2
In this case, we will delete the root element from the rightmost heap, arrange the heap as a
normal heap but exclude the element not following the min-heap criteria to a singleton heap.
Smooth Sort
The smooth sort was implemented in 3 different phases, each phase making the algorithm
more efficient.
If we perform the previous algorithm in an explicit manner (with converting the array to a heap
and performing operations over there instead of the array itself), we get the worst case
complexity of O(nlogn) and an extra O(n) memory to maintain the binary heap.
Thus, we prefer to convert the explicit heap to a mostly implicit leonardo heap as it only takes
O(logn) extra space instead of O(n).
Smooth Sort: Conversion to a Mostly Implicit Heap
We know how to represent a single heap in an implicit manner but leonardo heap is practically
a junction of many heaps altogether.
Order: Every leonardo number has an order that is the index of the number where it lies
in the leonardo sequence.
A singleton leonardo heap can be simply represented by an array in the same manner as we
used to do with simple heaps
Smooth Sort: Conversion to a Mostly Implicit Heap
For a complete forest, we simply represent individual trees implicitly and concatenate the
arrays.
Alongside, we keep on maintaining another auxiliary array which stores the sizes of the
concatenated arrays (or the individual leonardo tres).
Smooth Sort
1) Construct a mostly implicit leonardo max heap from the input sequence
2) While the heap is not empty, remove the maximum element from the heap and place it
at the back of the sequence
3) Rebalance the max-heap.
This only takes the worst case complexity from O(n) to O(logn)
THANKS