Quicksort implementation in place.

master
ben-burlingham 10 years ago
parent 12e2d955e4
commit 9101efa9f7
  1. 173
      index.html

@ -5,17 +5,176 @@
<title>D3</title>
<script type='text/javascript' src='vendor/d3/d3.min.js'></script>
<style type='text/css'></style>
<style type='text/css'>
html, body {
margin:0;
}
.quicksort-random {
display:block;
height:60px;
margin:0 auto;
width:1198px;
}
</style>
</head>
<body>
<script type='text/javascript'>
var dataset = [ 5, 10, 15, 20, 25 ];
var swatchH = 50;
var swatchW = 10;
var dataset = [];
// TODO namespace this
(function populate() {
var len = 100;
var r, g, b;
for (var i = 0; i < len; i++) {
dataset.push({
x: 0,
y: 20,
r: 0, //Math.floor((len - i) * 255 / len),
g: 0,
b: Math.floor(i * 255 / len)
});
};
}());
dataset = shuffle(dataset);
var svg = d3.select('body').append('svg')
.attr('class', 'quicksort-random');
var rectangles = svg.selectAll('rect')
.data(dataset).enter()
.append('rect')
.attr('height', swatchH)
.attr('width', swatchW)
// .attr('')
.attr('fill', function fill(d) {
return `rgb(${d.r}, ${d.g}, ${d.b})`;
})
.attr('y', function y(d) { return d.y; })
.attr('x', function x(d) { return d.x; })
.transition(500)
.attr('x', function xb(d, i) {
dataset[i].x = i * (swatchW + 2);
return dataset[i].x;
});
function visualSwap(indexA, indexB) {
// Move up
// NOTE Two way binding here between dataset and function parameter
rectangles
.transition()
.duration(100)
.attr('y', function ya(d, i) {
if (i === indexA || i === indexB) {
dataset[i].y = 5;
}
return dataset[i].y; // NOTE d[i].y has been modified too. But, the bound value in the dataset
// will not be updated until after the chain is completed, so it has to be explicitly defined here.
})
// Switch places
// NOTE discuss chained transitions: http://bl.ocks.org/mbostock/1125997
.transition()
.duration(500)
.attr('x', function xa(d, i) {
if (i === indexA) {
var tmp = dataset[indexA].x;
dataset[indexA].x = dataset[indexB].x;
dataset[indexB].x = tmp;
}
return d.x;
})
// Move down
.transition()
.duration(100)
.attr('y', function ya(d, i) {
if (i === indexA || i === indexB) {
dataset[i].y = 20;
}
return dataset[i].y;
})
};
function highlight(index) {
svg.selectAll('rect')
.attr('stroke', function(d, i) { if (i === index) { return 'lime'; } })
.attr('stroke-width', function(d, i) { if (i === index) { return 4; } });
};
function unhighlightAll(index) {
svg.selectAll('rect')
.attr('stroke', function(d, i) { return null; })
.attr('stroke-width', function(d, i) { return null; });
};
// NOTE fisher-yates, http://bost.ocks.org/mike/algorithms/
function shuffle(arr) {
var n = arr.length, t, i;
while (n) {
i = Math.random() * n-- | 0; // 0 ≤ i < n
t = arr[n];
arr[n] = arr[i];
arr[i] = t;
}
return arr;
};
// visualSwap(0, 1);
function quicksort(arr, startIndex, endIndex) {
if (endIndex - startIndex <= 0) {
return;
}
var left = startIndex;
var right = endIndex;
unhighlightAll();
var pivotIndex = Math.floor((right + left) / 2);
var pval = arr[pivotIndex].b;
var tmp;
highlight(pivotIndex);
while (left <= right) {
while (arr[left].b < pval) {
left++;
}
while (arr[right].b > pval) {
right--;
}
if (left <= right) {
tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
visualSwap(left, right);
left++;
right--;
}
}
quicksort(arr, startIndex, right);
quicksort(arr, left, endIndex);
};
quicksort(dataset, 0, dataset.length - 1);
console.error(dataset);
// var instructions = [];
// instructions.push('M ' + (50 * i) + ',50');
// instructions.push('A 50,50 0 0,1 ' + (50 * (i + 1)) + ',0');
// instructions.push('L ' + (50 * (i + 1)) + ',50');
// instructions.push('L ' + (50 * i) + ',50');
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text(function(d) { return d; });
</script>
</body>
</html>

Loading…
Cancel
Save