Skip to content

Instantly share code, notes, and snippets.

@stev47
Forked from anotherjavadude/index.html
Created July 26, 2012 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stev47/3181499 to your computer and use it in GitHub Desktop.
Save stev47/3181499 to your computer and use it in GitHub Desktop.
Building a heap from array
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<script type="text/javascript" src="http://d3js.org/d3.v2.js"></script>
<script type="text/javascript" src="mootools-core.js"></script>
<script type="text/javascript" src="mootools-more.js"></script>
<script type="text/javascript" src="heap.js"></script>
<style>
.link {
fill: none;
stroke: #999;
stroke-width: 2px;
}
.node ellipse {
fill: #FFF;
stroke: #000;
stroke-width: 1px;
}
</style>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
function create_sample (n) {
var array = [];
for (var i = 0; i < n; i++)
array[i] = i;
for (var i = 0; i < n; i++) {
var j = Math.floor(Math.random()*n);
var tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
return array;
}
// "vis" actually holds the svg-group element
var vis = d3.select("#viz").append("svg")
.attr("width", 940)
.attr("height", 400)
.append("g")
.attr("transform", "translate(0, 40)");
var tree = d3.layout.tree()
.size([940, 300]);
var diagonal = d3.svg.diagonal();
function update (tree_data) {
var tree = d3.layout.tree().size([940,300])
tree.separation(function (a, b) {
return (a.parent == b.parent)? 10 : 12;
});
var nodes = tree.nodes(tree_data);
var link = vis.selectAll("path.link") // "path.link" is a css selector (doesn't matter here)
.data(tree.links(nodes))
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = vis.selectAll("g.node")
.data(nodes, function (d) {
return d.value;
});
node.select("ellipse").transition().style("fill", function (d) {
if (d.status == "heapify")
return "#F99";
if (d.status == "compare")
return "#FF9";
return "#FFF";
})
node.transition().delay(100)
.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
})
var new_node = node.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
new_node.append("ellipse")
.attr("rx", 17)
.attr("ry", function(d) {
return 30 / d.depth;
})
new_node.append("text")
.attr("dy", "0.5ex")
.attr("text-anchor", "middle")
.text(function(d) { return d.value; });
node.exit()
.remove();
}
var my_heap = new Heap(create_sample(50), 2);
function heap_state_update () {
if (my_heap.states.length <= 0) {
return;
} else {
update(my_heap.states.shift());
setTimeout(heap_state_update, 500);
}
}
heap_state_update();
</script>
</body>
</html>
/*
A heap is represented as an object.
Each node has an attribute "value" containing the node value
and an attribute "children" containing an array of child nodes (if any)
*/
var Heap = new Class ({
states: [],
heap: [],
initialize: function(values, num_children) {
// number of tree nodes
this.n = values.length;
for (var i = 0; i < this.n; i++) {
this.heap.push({
value : values[i]
});
}
// number of children for each node
this.m = num_children;
// push initial state
this.states.push(this.getTree());
for (var node = this.n - 1; node >= 0; node--) {
this.heapify(node);
}
this.states.push(this.getTree());
},
swap: function (a, b) {
var tmp = this.heap[a].value;
this.heap[a].value = this.heap[b].value;
this.heap[b].value = tmp;
},
heapify: function (node) {
if (this.m * node + 1 > Math.min(this.n - 1, this.m * (node + 1)))
return false;
this.heap[node].status = "heapify";
var min = node;
for (var child = this.m * node + 1; child <= Math.min(this.n - 1, this.m * (node + 1)); child++) {
this.heap[child].status = "compare";
if (this.heap[child].value < this.heap[min].value)
min = child;
}
this.states.push(this.getTree());
for (var child = this.m * node + 1; child <= Math.min(this.n - 1, this.m * (node + 1)); child++) {
this.heap[child].status = "";
}
if (min != node) {
this.swap(node, min);
// push current state;
this.states.push(this.getTree());
this.heapify(min);
this.heap[node].status = "";
return true;
} else {
this.heap[node].status = "";
return false;
}
},
getNodeTree: function (node) {
var obj = Object.clone(this.heap[node]);
obj.children = [];
for (var child = this.m * node + 1; child <= Math.min(this.n - 1, this.m * (node + 1)); child++) {
obj.children.push(this.getNodeTree(child));
}
return obj;
},
getTree: function () {
return this.getNodeTree(0);
}
})
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<script type="text/javascript" src="http://d3js.org/d3.v2.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-yui-compressed.js"></script>
<script type="text/javascript" src="heap.js"></script>
<style>
.link {
fill: none;
stroke: #999;
stroke-width: 2px;
}
.node ellipse {
fill: #FFF;
stroke: #000;
stroke-width: 1px;
}
</style>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
function create_sample (n) {
var array = [];
for (var i = 0; i < n; i++)
array[i] = i;
for (var i = 0; i < n; i++) {
var j = Math.floor(Math.random()*n);
var tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
return array;
}
// "vis" actually holds the svg-group element
var vis = d3.select("#viz").append("svg")
.attr("width", 940)
.attr("height", 400)
.append("g")
.attr("transform", "translate(0, 40)");
var tree = d3.layout.tree()
.size([940, 300]);
var diagonal = d3.svg.diagonal();
function update (tree_data) {
var tree = d3.layout.tree().size([940,300])
tree.separation(function (a, b) {
return (a.parent == b.parent)? 10 : 12;
});
var nodes = tree.nodes(tree_data);
var link = vis.selectAll("path.link") // "path.link" is a css selector (doesn't matter here)
.data(tree.links(nodes))
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = vis.selectAll("g.node")
.data(nodes, function (d) {
return d.value;
});
node.select("ellipse").transition()
.style("fill", function (d) {
if (d.status == "heapify")
return "#F99";
if (d.status == "compare")
return "#FF9";
return "#FFF";
})
.attr("rx", function(d) {
return 50 / Math.pow(d.depth + 1, 0.8);
});
node.transition()
.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
var new_node = node.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
new_node.append("ellipse")
.attr("ry", 13)
.attr("rx", function(d) {
return 50 / Math.pow(d.depth + 1, 0.8);
});
new_node.append("text")
.attr("dy", "0.5ex")
.attr("text-anchor", "middle")
.text(function(d) { return d.value; });
node.exit()
.remove();
}
var my_heap = new Heap(create_sample(50), 2);
function heap_state_update () {
if (my_heap.states.length <= 0) {
return;
} else {
update(my_heap.states.shift());
setTimeout(heap_state_update, 500);
}
}
heap_state_update();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment