|
|
|
@ -14,109 +14,220 @@ |
|
|
|
|
Here are visualizations of common sorting algorithms. Use the comparisons counter |
|
|
|
|
and number of items to observe the performance of each randomized case. |
|
|
|
|
|
|
|
|
|
<a href='http://gogs.benburlingham.com/ben.burlingham/d3-sort-visualization' target='_new'>[Source repository]</a> |
|
|
|
|
<br> |
|
|
|
|
<br><br> |
|
|
|
|
|
|
|
|
|
All source data is shuffled using the <a href='http://bost.ocks.org/mike/algorithms/'>Fisher-Yates</a> algorithm. |
|
|
|
|
|
|
|
|
|
<br><br> |
|
|
|
|
|
|
|
|
|
There's a fun clip about the sounds of sorting <a href="https://www.youtube.com/watch?v=t8g-iYGHpEA">here</a>. |
|
|
|
|
|
|
|
|
|
<br><br> |
|
|
|
|
|
|
|
|
|
<h2>Quick sort discussion</h2> |
|
|
|
|
|
|
|
|
|
<a class='src' href='http://gogs.benburlingham.com/ben.burlingham/d3-sort-visualization/src/master/js/quicksort.js'>Source Code</a> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
<span class='title'>Implementation</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Select a pivot element anywhere in the list</li> |
|
|
|
|
<li>Uses "left" and "right" markers that approach each other from opposite ends of the list</li> |
|
|
|
|
<li>Left marker halts if its current value is greater than pivot</li> |
|
|
|
|
<li>Right marker halts if its current value is less than pivot</li> |
|
|
|
|
<li>Swap after both markers are halted, then continue moving inwards</li> |
|
|
|
|
<li>Once markers pass eachother, recurse for sublists on each side of pivot</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<h2>Quicksort discussion</h2> |
|
|
|
|
<p> |
|
|
|
|
used by chrome.<br> |
|
|
|
|
source code link |
|
|
|
|
<span class='title'>Notes</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>"Conquer and divide" algorithm</li> |
|
|
|
|
<li>Performance depends heavily on pivot selection</li> |
|
|
|
|
<li>O(n) time possible with partitioning</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<div class="sorter" |
|
|
|
|
data-algorithm='quick' |
|
|
|
|
data-stable='Maybe' |
|
|
|
|
data-adaptive='Maybe' |
|
|
|
|
data-worst-perf='O(n + m + 3k)' |
|
|
|
|
data-avg-perf='O(n + m + 3k)' |
|
|
|
|
data-best-perf='O(n + m + 3k)' |
|
|
|
|
data-worst-memory='0 (in place)' |
|
|
|
|
data-stable='No' |
|
|
|
|
data-adaptive='No' |
|
|
|
|
data-worst-perf='O (n^2)' |
|
|
|
|
data-avg-perf='O (n log n)' |
|
|
|
|
data-best-perf='O (n log n)' |
|
|
|
|
data-worst-memory='0' |
|
|
|
|
></div> |
|
|
|
|
|
|
|
|
|
<h2>Mergesort discussion</h2> |
|
|
|
|
<h2>Merge sort discussion</h2> |
|
|
|
|
|
|
|
|
|
<a class='src' href='http://gogs.benburlingham.com/ben.burlingham/d3-sort-visualization/src/master/js/mergesort.js'>Source Code</a> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
<span class='title'>Implementation</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Recursively split array until only single element slices remain.</li> |
|
|
|
|
<li>Consider two slices. Compare their heads and unshift minimum into a result array.</li> |
|
|
|
|
<li>Continue comparing heads and unshifting until the two slices are empty.</li> |
|
|
|
|
<li>Build result arrays from all the slices.</li> |
|
|
|
|
<li>Recurse the comparison process on the result arrays.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
used by firefox and safari.<br> |
|
|
|
|
helpful: http://stackoverflow.com/questions/2967153/space-requirements-of-a-merge-sort<br> |
|
|
|
|
source code link |
|
|
|
|
<span class='title'>Notes</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Top down variant: Recursively split into halves, sort halves depth first, ending with original two halves. Tree-like. Implemented here.</li> |
|
|
|
|
<li>Bottom up variant: Split fixed intervals, sort each interval, join into full array, split larger interval, repeat.</li> |
|
|
|
|
<li>Natural variant: Bottom up, but with adaptive interval selection over existing ordering.</li> |
|
|
|
|
<li><a href="http://stackoverflow.com/questions/10153393/mergesort-is-bottom-up-faster-than-top-down">Discussion of variants</a></li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<div class="sorter" |
|
|
|
|
data-algorithm='merge' |
|
|
|
|
data-stable='Maybe' |
|
|
|
|
data-adaptive='Maybe' |
|
|
|
|
data-worst-perf='O(n + m + 3k)' |
|
|
|
|
data-avg-perf='O(n + m + 3k)' |
|
|
|
|
data-best-perf='O(n + m + 3k)' |
|
|
|
|
data-worst-memory='0 (in place)' |
|
|
|
|
data-stable='Yes' |
|
|
|
|
data-adaptive='Yes' |
|
|
|
|
data-worst-perf='O (n log n)' |
|
|
|
|
data-avg-perf='O (n log n)' |
|
|
|
|
data-best-perf='O (n log n)' |
|
|
|
|
data-worst-memory='O (n)' |
|
|
|
|
></div> |
|
|
|
|
|
|
|
|
|
<h2>Selection sort discussion</h2> |
|
|
|
|
|
|
|
|
|
<a class='src' href='http://gogs.benburlingham.com/ben.burlingham/d3-sort-visualization/src/master/js/selectionsort.js'>Source Code</a> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
<span class='title'>Implementation</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Consider [0]. Compare it to the rest of the elements to find the minimum value.</li> |
|
|
|
|
<li>Swap [0] with the index of the minimum. [0] is now finished.</li> |
|
|
|
|
<li>Proceed to [1]. Repeat.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
http://stackoverflow.com/questions/15799034/insertion-sort-vs-selection-sort <br> |
|
|
|
|
finds upstram minimum and swaps with current.<br> |
|
|
|
|
source code link |
|
|
|
|
<span class='title'>Notes</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>To remember: selection sort selects the minimum.</li> |
|
|
|
|
<li>Be aware of the unstable version, where a swap is greedy.</li> |
|
|
|
|
<li>No other sorting algorithm has less data movement (<a href="http://rosettacode.org/wiki/Sorting_algorithms/Selection_sort">Rosetta Code</a>)</li> |
|
|
|
|
<li>Good for cases where writes are expensive.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<div class="sorter" |
|
|
|
|
data-algorithm='selection' |
|
|
|
|
data-stable='Maybe' |
|
|
|
|
data-adaptive='Maybe' |
|
|
|
|
data-worst-perf='O(n + m + 3k)' |
|
|
|
|
data-avg-perf='O(n + m + 3k)' |
|
|
|
|
data-best-perf='O(n + m + 3k)' |
|
|
|
|
data-worst-memory='0 (in place)'> |
|
|
|
|
data-stable='Yes' |
|
|
|
|
data-adaptive='No' |
|
|
|
|
data-worst-perf='O (n^2)' |
|
|
|
|
data-avg-perf='O (n^2)' |
|
|
|
|
data-best-perf='O (n^2)' |
|
|
|
|
data-worst-memory='0'> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<h2>Insertion sort discussion</h2> |
|
|
|
|
|
|
|
|
|
<a class='src' href='http://gogs.benburlingham.com/ben.burlingham/d3-sort-visualization/src/master/js/insertionsort.js'>Source Code</a> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
how is this different from bubble and selection. <br> |
|
|
|
|
swap. highlight. fade.<br> |
|
|
|
|
source code link |
|
|
|
|
<span class='title'>Implementation</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Compare [1] and [0]. Swap if [0] > [1].</li> |
|
|
|
|
<li>Compare [2] and [1]. Swap if needed. Continue swapping downward one by one until no swap is needed.</li> |
|
|
|
|
<li>Repeat with [3], [4], etc. until end of the array.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
<span class='title'>Notes</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Simplicity can make insertion sort a good choice for small arrays.</li> |
|
|
|
|
<li>Similar to selection sort, but uses bubbling rather than minimums.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<div class="sorter" |
|
|
|
|
data-algorithm='insertion' |
|
|
|
|
data-stable='Maybe' |
|
|
|
|
data-adaptive='Maybe' |
|
|
|
|
data-worst-perf='O(n + m + 3k)' |
|
|
|
|
data-avg-perf='O(n + m + 3k)' |
|
|
|
|
data-best-perf='O(n + m + 3k)' |
|
|
|
|
data-worst-memory='0 (in place)' |
|
|
|
|
data-stable='Yes' |
|
|
|
|
data-adaptive='Yes' |
|
|
|
|
data-worst-perf='O (n^2)' |
|
|
|
|
data-avg-perf='O (n^2)' |
|
|
|
|
data-best-perf='O (n)' |
|
|
|
|
data-worst-memory='0' |
|
|
|
|
></div> |
|
|
|
|
|
|
|
|
|
<h2>Shellsort discussion</h2> |
|
|
|
|
|
|
|
|
|
<a class='src' href='http://gogs.benburlingham.com/ben.burlingham/d3-sort-visualization/src/master/js/shellsort.js'>Source Code</a> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
<span class='title'>Implementation</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Decide on a gap width. 3 is used here.</li> |
|
|
|
|
<li>Start at [3]. Compare to [0]. Swap if [0] > [3].</li> |
|
|
|
|
<li>Move to [4]. Compare to [1]. Swap if necessary.</li> |
|
|
|
|
<li>Move to [5]. Compare to [2]. Swap if necessary.</li> |
|
|
|
|
<li>Continue the pattern and bubble downstream, exactly like insertion sort but with a gap of 3, not 1.</li> |
|
|
|
|
<li>After the end of the list is reached, it is weakly sorted. Perform a final insertion sort.</li> |
|
|
|
|
<li>Note: Insertion sort is a shell sort with a gap of 1.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
several ways to pick gap width, but dependence on input data makes gap selection trivial.<br> |
|
|
|
|
Insertion sort with gap of 1.<br> |
|
|
|
|
source code link |
|
|
|
|
<span class='title'>Notes</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Weakly sorts elements to prepare for final pass using different sort algorithm</li> |
|
|
|
|
<li>Average performance depends on gap selection, but...</li> |
|
|
|
|
<li>Dependence on input data makes gap selection highly subjective</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<div class="sorter" |
|
|
|
|
data-algorithm='shell' |
|
|
|
|
data-stable='Maybe' |
|
|
|
|
data-adaptive='Maybe' |
|
|
|
|
data-worst-perf='O(n + m + 3k)' |
|
|
|
|
data-avg-perf='O(n + m + 3k)' |
|
|
|
|
data-best-perf='O(n + m + 3k)' |
|
|
|
|
data-worst-memory='0 (in place)' |
|
|
|
|
data-stable='No' |
|
|
|
|
data-adaptive='Yes' |
|
|
|
|
data-worst-perf='O (n^2)' |
|
|
|
|
data-avg-perf='-' |
|
|
|
|
data-best-perf='O (n lg n)' |
|
|
|
|
data-worst-memory='n' |
|
|
|
|
></div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Bubble sort discussion</h2> |
|
|
|
|
|
|
|
|
|
<a class='src' href='http://gogs.benburlingham.com/ben.burlingham/d3-sort-visualization/src/master/js/bubblesort.js'>Source Code</a> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
<span class='title'>Implementation</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>Order [1] and [0].</li> |
|
|
|
|
<li>Order [2] and [1].</li> |
|
|
|
|
<li>Continue to the end. Note that there is at most one swap per index.</li> |
|
|
|
|
<li>Repeat the process until fully ordered. Keep a boolean that shows if swaps have been made.</li> |
|
|
|
|
<li>Once there is a pass without swaps, all elements have bubbled down to their proper positions.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
how is this different from insertion and selection sorts. <br> |
|
|
|
|
talk about turtles and rabbits, because search loops from beginning each time. Every number out of place means a new pass must be done.<br> |
|
|
|
|
source code link |
|
|
|
|
<span class='title'>Notes</span> |
|
|
|
|
<ul> |
|
|
|
|
<li>If even one number is out of place means a new pass must be done.</li> |
|
|
|
|
<li>"Turtles" are small values that crawl slowly toward their position near the front.</li> |
|
|
|
|
<li>"Rabbits" are large values that hop quickly to their position near the end.</li> |
|
|
|
|
<li>Variations on bubble sort (cocktail sort, comb sort) try to address the turtle problem.</li> |
|
|
|
|
</ul> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<div class="sorter" |
|
|
|
|
data-algorithm='bubble' |
|
|
|
|
data-stable='Maybe' |
|
|
|
|
data-adaptive='Maybe' |
|
|
|
|
data-worst-perf='O(n + m + 3k)' |
|
|
|
|
data-avg-perf='O(n + m + 3k)' |
|
|
|
|
data-best-perf='O(n + m + 3k)' |
|
|
|
|
data-worst-memory='0 (in place)' |
|
|
|
|
data-stable='Yes' |
|
|
|
|
data-adaptive='Yes' |
|
|
|
|
data-worst-perf='O (n^2)' |
|
|
|
|
data-avg-perf='O (n^2)' |
|
|
|
|
data-best-perf='O (n)' |
|
|
|
|
data-worst-memory='0' |
|
|
|
|
></div> |
|
|
|
|
|
|
|
|
|
<!-- |
|
|
|
@ -178,3 +289,4 @@ |
|
|
|
|
</script> |
|
|
|
|
</body> |
|
|
|
|
</html> |
|
|
|
|
O (n) |
|
|
|
|