Finalizing discussion points.

master
ben-burlingham 10 years ago
parent 35303a9bc9
commit 1fdee61243
  1. 11
      css/style.css
  2. 228
      index.html
  3. 6
      js/itemgroup.js
  4. 1
      js/sorter.js
  5. 6
      js/visualizer-dom.js
  6. 10
      js/visualizer.js

@ -1,3 +1,13 @@
.src {
display:block;
font-size:14px;
margin:10px 0;
}
.title {
font-weight:bold;
}
.sorter {
background:#f4f4f4;
border:1px solid #bbb;
@ -38,6 +48,7 @@
.sorter-properties {
height:40px;
left:10px;
line-height:normal;
position:absolute;
top:210px;
width:570px;

@ -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)

@ -47,11 +47,6 @@ var Itemgroup = {
var x, a, b;
var len = group.selectAll('g')[0].length;
// NOTE pitfalls in the swapping problem.
// NOTE Two way binding here between dataset and function parameter?
// NOTE swapping will not reorder index and i parameter will be off
// NOTE discuss chained transitions: http://bl.ocks.org/mbostock/1125997
// Animate a node swap which will be quietly undone after completion.
group.selectAll('g').transition().duration(delay - 100)
.attr('transform', function transform(d, i) {
@ -120,7 +115,6 @@ var Itemgroup = {
*
*/
text: function text(group, delay, which, text) {
// NOTE http://stackoverflow.com/questions/28390754/get-one-element-from-d3js-selection-by-index
group.selectAll('g')
.filter(function filter(d, i) { return i === which; })
.select('text').text(text);

@ -10,7 +10,6 @@ var Sorter = function() {
this.comparisons = [];
};
// NOTE fisher-yates, http://bost.ocks.org/mike/algorithms/
/**
* Returns copy of an array shuffled using Fisher-Yates.
*/

@ -207,7 +207,7 @@ Visualizer.prototype.initProperties = function() {
div3.className = 'property p3';
var title3 = document.createElement('div');
title3.innerHTML = 'Worst Performance';
title3.innerHTML = 'Worst Perf.';
title3.className = 'title';
div3.appendChild(title3);
@ -221,7 +221,7 @@ Visualizer.prototype.initProperties = function() {
div4.className = 'property p4';
var title4 = document.createElement('div');
title4.innerHTML = 'Avg Performance';
title4.innerHTML = 'Avg Perf.';
title4.className = 'title';
div4.appendChild(title4);
@ -235,7 +235,7 @@ Visualizer.prototype.initProperties = function() {
div5.className = 'property p5';
var title5 = document.createElement('div');
title5.innerHTML = 'Best Performance';
title5.innerHTML = 'Best Perf.';
title5.className = 'title';
div5.appendChild(title5);

@ -102,16 +102,10 @@ Visualizer.prototype.go = function() {
action[0].apply(this, args);
// TODO add links to stats
// TODO heap sort
// TODO radix sort
// TODO in quicksort, change color or element that is in final position
// NOTE functional programming discussion
// NOTE interesting (anti?)pattern here.
// NOTE use of call() vs apply() (apply only delivered first array item as string)
// if (typeof operation === 'function') {
// operation.call(this, action);
// TODO comb sort
// TODO cocktail sort
if (delay === 0) {
this.actionIndex++;

Loading…
Cancel
Save