If your goal is to gain some insight into the operation of the algorithm, then knowing the specific value and place of the elements is less important than watching the run lengths on the stack. These run lengths are visible in the saw tooths that appear in Stefan Pochmann's animation.
These run lengths reveal the logarithmic limit on growth of the stack of pointers (indices) into the data array which is an important feature of the basic timsort algorithm. The following is an example of a clearer presentation of this, that just shows the stack indices:
entry [0, 53, 106]
exit [0, 106]
entry [0, 106, 159, 212]
exit [0, 106, 212]
entry [0, 106, 212]
exit [0, 212]
entry [0, 212, 265, 318]
exit [0, 212, 318]
entry [0, 212, 318, 371, 424]
exit [0, 212, 318, 424]
entry [0, 212, 318, 424]
exit [0, 212, 424]
entry [0, 212, 424]
exit [0, 424]
entry [0, 424, 477, 530]
exit [0, 424, 530]
entry [0, 424, 530, 583, 636]
exit [0, 424, 530, 636]
entry [0, 424, 530, 636]
exit [0, 424, 636]
entry [0, 424, 636, 689, 742]
exit [0, 424, 636, 742]
entry [0, 424, 636, 742, 795, 836]
exit [0, 424, 636, 742, 836]
entry [0, 424, 636, 742, 836]
exit [0, 424, 636, 836]
entry [0, 424, 636, 836]
exit [0, 424, 836]
entry [0, 424, 836]
exit [0, 836]
Functional trial 0 sorted 836 random data items.
Data between indices has been sorted in ascending order. The label entry
shows the stack state at the merge routine entry point and exit
shows the state on exit. When entry
equals the previous exit
, multiple runs are being merged due to repeated failure of the invariant prior to proceeding with creation of the next run. Data from the stack top index to the size of the array is data that timsort has not yet examined in its linear scan of the array. When the stack top index equals the array size, timsort has finished scanning, but may need to finalize with some merging. In this example, timsort generates two runs before the invariant fails for the first time and a merge commences, and finalizes by merging five runs.
While this type of output could be generated by a more complex postmortem using Stefan Pochmann's code, this data was generated using the implementation of timsort found here:
https://gist.github.com/ruminations/89a045dc0ef7edfb92304a0de0752ee0
by uncommenting the two ##print ...
statements in the merge
method (lines 263
and 303
) and adding a break
statement after line 391
in the test suite at the end. The code is useful for playing around with the algorithm and gaining some intuitive understanding of its operation.