879 行
24 KiB
JavaScript

// Copyright 2011 David Galles, University of San Francisco. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of the University of San Francisco
FibonacciHeap.LINK_COLOR = "#007700";
FibonacciHeap.FOREGROUND_COLOR = "#007700";
FibonacciHeap.BACKGROUND_COLOR = "#EEFFEE";
FibonacciHeap.INDEX_COLOR = "#0000FF";
FibonacciHeap.DEGREE_OFFSET_X = -20;
FibonacciHeap.DEGREE_OFFSET_Y = -20;
FibonacciHeap.DELETE_LAB_X = 30;
FibonacciHeap.DELETE_LAB_Y = 50;
FibonacciHeap.NODE_WIDTH = 60;
FibonacciHeap.NODE_HEIGHT = 70
FibonacciHeap.STARTING_X = 70;
FibonacciHeap.INSERT_X = 30;
FibonacciHeap.INSERT_Y = 25
FibonacciHeap.STARTING_Y = 100;
FibonacciHeap.MAX_DEGREE = 7;
FibonacciHeap.DEGREE_ARRAY_ELEM_WIDTH = 30;
FibonacciHeap.DEGREE_ARRAY_ELEM_HEIGHT = 30;
FibonacciHeap.DEGREE_ARRAY_START_X = 500;
FibonacciHeap.INDEGREE_ARRAY_START_Y = 50;
FibonacciHeap.TMP_PTR_Y = 60;
function FibonacciHeap(am, w, h)
{
this.init(am, w, h);
}
FibonacciHeap.prototype = new Algorithm();
FibonacciHeap.prototype.constructor = FibonacciHeap;
FibonacciHeap.superclass = Algorithm.prototype;
FibonacciHeap.prototype.init = function(am, w, h)
{
FibonacciHeap.superclass.init.call(this, am, w, h);
this.addControls();
this.treeRoot = null;
this.currentLayer = 1;
this.animationManager.setAllLayers([0,this.currentLayer]);
this.minID = 0;
this.nextIndex = 1;
}
FibonacciHeap.prototype.addControls = function()
{
this.controls = [];
this.insertField = addControlToAlgorithmBar("Text", "");
this.insertField.onkeydown = this.returnSubmit(this.insertField, this.insertCallback.bind(this), 4);
this.controls.push(this.insertField);
this.insertButton = addControlToAlgorithmBar("Button", "添加");
this.insertButton.onclick = this.insertCallback.bind(this);
this.controls.push(this.insertButton);
this.removeSmallestButton = addControlToAlgorithmBar("Button", "Remove Smallest");
this.removeSmallestButton.onclick = this.removeSmallestCallback.bind(this);
this.controls.push(this.removeSmallestButton);
this.clearHeapButton = addControlToAlgorithmBar("Button", "Clear Heap");
this.clearHeapButton.onclick = this.clearCallback.bind(this);
this.controls.push(this.clearHeapButton);
var radioButtonList = addRadioButtonGroupToAlgorithmBar(["Logical Representation",
"Internal Representation",
],
"BQueueRep");
radioButtonList[0].onclick = this.representationChangedHandler.bind(this, true);
radioButtonList[1].onclick = this.representationChangedHandler.bind(this, false);
radioButtonList[0].checked = true;
}
FibonacciHeap.prototype.representationChangedHandler = function(logicalRep, event)
{
if (logicalRep)
{
this.animationManager.setAllLayers([0,1]);
this.currentLayer = 1;
}
else
{
this.animationManager.setAllLayers([0,2]);
this.currentLayer = 2;
}
}
FibonacciHeap.prototype.setPositions = function(tree, xPosition, yPosition)
{
if (tree != null)
{
if (tree.degree == 0)
{
tree.x = xPosition;
tree.y = yPosition;
return this.setPositions(tree.rightSib, xPosition + FibonacciHeap.NODE_WIDTH, yPosition);
}
else if (tree.degree == 1)
{
tree.x = xPosition;
tree.y = yPosition;
this.setPositions(tree.leftChild, xPosition, yPosition + FibonacciHeap.NODE_HEIGHT);
return this.setPositions(tree.rightSib, xPosition + FibonacciHeap.NODE_WIDTH, yPosition);
}
else
{
var treeWidth = Math.pow(2, tree.degree - 1);
tree.x = xPosition + (treeWidth - 1) * FibonacciHeap.NODE_WIDTH;
tree.y = yPosition;
this.setPositions(tree.leftChild, xPosition, yPosition + FibonacciHeap.NODE_HEIGHT);
return this.setPositions(tree.rightSib, xPosition + treeWidth * FibonacciHeap.NODE_WIDTH, yPosition);
}
}
return xPosition;
}
FibonacciHeap.prototype.moveTree = function(tree)
{
if (tree != null)
{
this.cmd("Move", tree.graphicID, tree.x, tree.y);
this.cmd("Move", tree.internalGraphicID, tree.x, tree.y);
this.cmd("Move", tree.degreeID, tree.x + FibonacciHeap.DEGREE_OFFSET_X, tree.y + FibonacciHeap.DEGREE_OFFSET_Y);
this.moveTree(tree.leftChild);
this.moveTree(tree.rightSib);
}
}
FibonacciHeap.prototype.insertCallback = function(event)
{
var insertedValue;
insertedValue = this.normalizeNumber(this.insertField.value, 4);
if (insertedValue != "")
{
this.insertField.value = "";
this.implementAction(this.insertElement.bind(this),insertedValue);
}
}
FibonacciHeap.prototype.clearCallback = function(event)
{
this.implementAction(this.clear.bind(this),"");
}
FibonacciHeap.prototype.clear = function()
{
this.commands = new Array();
this.deleteTree(this.treeRoot);
this.cmd("Delete", this.minID);
this.nextIndex = 1;
this.treeRoot = null;
this.minElement = null;
return this.commands;
}
FibonacciHeap.prototype.deleteTree = function(tree)
{
if (tree != null)
{
this.cmd("Delete", tree.graphicID);
this.cmd("Delete", tree.internalGraphicID);
this.cmd("Delete", tree.degreeID);
this.deleteTree(tree.leftChild);
this.deleteTree(tree.rightSib);
}
}
FibonacciHeap.prototype.reset = function()
{
this.treeRoot = null;
this.nextIndex = 1;
}
FibonacciHeap.prototype.removeSmallestCallback = function(event)
{
this.implementAction(this.removeSmallest.bind(this),"");
}
FibonacciHeap.prototype.removeSmallest = function(dummy)
{
this.commands = new Array();
if (this.treeRoot != null)
{
var tmp;
var prev;
if (this.minElement == this.treeRoot) {
this.treeRoot = this.treeRoot.rightSib;
prev = null;
}
else
{
for (prev = this.treeRoot; prev.rightSib != this.minElement; prev = prev.rightSib) ;
prev.rightSib = prev.rightSib.rightSib;
}
var moveLabel = this.nextIndex++;
this.cmd("SetText", this.minElement.graphicID, "");
this.cmd("SetText", this.minElement.internalGraphicID, "");
this.cmd("CreateLabel", moveLabel, this.minElement.data, this.minElement.x, this.minElement.y);
this.cmd("Move", moveLabel, FibonacciHeap.DELETE_LAB_X, FibonacciHeap.DELETE_LAB_Y);
this.cmd("Step");
this.cmd("Delete", this.minID);
var childList = this.minElement.leftChild;
if (this.treeRoot == null)
{
this.cmd("Delete", this.minElement.graphicID);
this.cmd("Delete", this.minElement.internalGraphicID);
this.cmd("Delete", this.minElement.degreeID);
this.treeRoot = childList;
this.minElement = null;
if (this.treeRoot != null)
{
for (tmp = this.treeRoot; tmp != null; tmp = tmp.rightSib)
{
if (this.minElement == null || this.minElement.data > tmp.data)
{
this.minElement = tmp;
}
}
this.cmd("CreateLabel", this.minID, "Min element", this.minElement.x, FibonacciHeap.TMP_PTR_Y);
this.cmd("Connect", this.minID,
this.minElement.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.minID,
this.minElement.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
}
this.SetAllTreePositions(this.treeRoot, []);
this.MoveAllTrees(this.treeRoot, []);
this.cmd("Delete", moveLabel);
return this.commands;
}
else if (childList == null)
{
if (prev != null && prev.rightSib != null)
{
this.cmd("Connect", prev.internalGraphicID,
prev.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", prev.rightSib.internalGraphicID,
prev.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
}
}
else
{
var tmp;
for (tmp = childList; tmp.rightSib != null; tmp = tmp.rightSib)
{
tmp.parent = null;
}
tmp.parent = null;
// TODO: Add in implementation links
if (prev == null)
{
this.cmd("Connect", tmp.internalGraphicID,
this.treeRoot.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.treeRoot.internalGraphicID,
tmp.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
tmp.rightSib = this.treeRoot;
this.treeRoot = childList;
}
else
{
this.cmd("Connect", prev.internalGraphicID,
childList.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", childList.internalGraphicID,
prev.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
if (prev.rightSib != null)
{
this.cmd("Connect", prev.rightSib.internalGraphicID,
tmp.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", tmp.internalGraphicID,
prev.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
}
tmp.rightSib = prev.rightSib;
prev.rightSib = childList;
}
}
this.cmd("Delete", this.minElement.graphicID);
this.cmd("Delete", this.minElement.internalGraphicID);
this.cmd("Delete", this.minElement.degreeID);
this.SetAllTreePositions(this.treeRoot, []);
this.MoveAllTrees(this.treeRoot, []);
this.fixAfterRemoveMin();
this.cmd("Delete", moveLabel);
}
return this.commands;
}
FibonacciHeap.prototype.insertElement = function(insertedValue)
{
this.commands = new Array();
var insertNode = new BinomialNode(insertedValue, this.nextIndex++, FibonacciHeap.INSERT_X, FibonacciHeap.INSERT_Y);
insertNode.internalGraphicID = this.nextIndex++;
insertNode.degreeID= this.nextIndex++;
this.cmd("CreateCircle", insertNode.graphicID, insertedValue, FibonacciHeap.INSERT_X, FibonacciHeap.INSERT_Y);
this.cmd("SetForegroundColor", insertNode.graphicID, FibonacciHeap.FOREGROUND_COLOR);
this.cmd("SetBackgroundColor", insertNode.graphicID, FibonacciHeap.BACKGROUND_COLOR);
this.cmd("SetLayer", insertNode.graphicID, 1);
this.cmd("CreateCircle", insertNode.internalGraphicID, insertedValue, FibonacciHeap.INSERT_X, FibonacciHeap.INSERT_Y);
this.cmd("SetForegroundColor", insertNode.internalGraphicID, FibonacciHeap.FOREGROUND_COLOR);
this.cmd("SetBackgroundColor", insertNode.internalGraphicID, FibonacciHeap.BACKGROUND_COLOR);
this.cmd("SetLayer", insertNode.internalGraphicID, 2);
this.cmd("CreateLabel", insertNode.degreeID, insertNode.degree, insertNode.x + FibonacciHeap.DEGREE_OFFSET_X, insertNode.y + FibonacciHeap.DEGREE_OFFSET_Y);
this.cmd("SetTextColor", insertNode.degreeID, "#0000FF");
this.cmd("SetLayer", insertNode.degreeID, 2);
this.cmd("Step");
if (this.treeRoot == null)
{
this.treeRoot = insertNode;
this.setPositions(this.treeRoot, FibonacciHeap.STARTING_X, FibonacciHeap.STARTING_Y);
this.moveTree(this.treeRoot);
this.cmd("CreateLabel", this.minID, "Min element", this.treeRoot.x, FibonacciHeap.TMP_PTR_Y);
this.minElement = this.treeRoot;
this.cmd("Connect", this.minID,
this.minElement.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.minID,
this.minElement.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
}
else
{
var tmp;
var prev;
if (this.minElement == this.treeRoot) {
insertNode.rightSib = this.treeRoot;
this.treeRoot = insertNode;
this.cmd("Connect", this.treeRoot.internalGraphicID,
this.treeRoot.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.treeRoot.rightSib.internalGraphicID,
this.treeRoot.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Step");
this.setPositions(this.treeRoot, FibonacciHeap.STARTING_X, FibonacciHeap.STARTING_Y);
if (this.minElement.data > insertNode.data)
{
this.cmd("Disconnect", this.minID, this.minElement.graphicID);
this.cmd("Disconnect", this.minID, this.minElement.internalGraphicID);
this.minElement = insertNode;
this.cmd("Connect", this.minID,
this.minElement.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.minID,
this.minElement.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
}
this.cmd("Move", this.minID, this.minElement.x, FibonacciHeap.TMP_PTR_Y);
this.moveTree(this.treeRoot);
}
else
{
for (prev = this.treeRoot; prev.rightSib != this.minElement; prev = prev.rightSib) ;
this.cmd("Disconnect", prev.internalGraphicID, prev.rightSib.internalGraphicID);
this.cmd("Disconnect", prev.rightSib.internalGraphicID, prev.internalGraphicID);
insertNode.rightSib = prev.rightSib;
prev.rightSib = insertNode;
this.cmd("Connect", prev.internalGraphicID,
prev.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", prev.rightSib.internalGraphicID,
prev.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
if (prev.rightSib.rightSib != null)
{
this.cmd("Connect", prev.rightSib.internalGraphicID,
prev.rightSib.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", prev.rightSib.rightSib.internalGraphicID,
prev.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
}
this.cmd("Step");
this.setPositions(this.treeRoot, FibonacciHeap.STARTING_X, FibonacciHeap.STARTING_Y);
if (this.minElement.data > insertNode.data)
{
this.cmd("Disconnect", this.minID, this.minElement.graphicID);
this.cmd("Disconnect", this.minID, this.minElement.internalGraphicID);
this.minElement = insertNode;
this.cmd("Connect", this.minID,
this.minElement.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.minID,
this.minElement.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
}
this.cmd("Move", this.minID, this.minElement.x, FibonacciHeap.TMP_PTR_Y);
this.moveTree(this.treeRoot);
}
}
return this.commands;
}
FibonacciHeap.prototype.fixAfterRemoveMin = function()
{
if (this.treeRoot == null)
return;
var degreeArray = new Array(FibonacciHeap.MAX_DEGREE);
var degreeGraphic = new Array(FibonacciHeap.MAX_DEGREE);
var indexID = new Array(FibonacciHeap.MAX_DEGREE);
var tmpPtrID = this.nextIndex++;
var i;
for (i = 0 ; i <= FibonacciHeap.MAX_DEGREE; i++)
{
degreeArray[i] = null;
degreeGraphic[i] = this.nextIndex++;
indexID[i] = this.nextIndex++;
this.cmd("CreateRectangle",
degreeGraphic[i],
" ",
FibonacciHeap.DEGREE_ARRAY_ELEM_WIDTH,
FibonacciHeap.DEGREE_ARRAY_ELEM_HEIGHT,
FibonacciHeap.DEGREE_ARRAY_START_X + i * FibonacciHeap.DEGREE_ARRAY_ELEM_WIDTH,
FibonacciHeap.INDEGREE_ARRAY_START_Y);
this.cmd("SetNull", degreeGraphic[i], 1);
this.cmd("CreateLabel", indexID[i], i, FibonacciHeap.DEGREE_ARRAY_START_X + i * FibonacciHeap.DEGREE_ARRAY_ELEM_WIDTH,
FibonacciHeap.INDEGREE_ARRAY_START_Y - FibonacciHeap.DEGREE_ARRAY_ELEM_HEIGHT);
this.cmd("SetTextColod", indexID[i], FibonacciHeap.INDEX_COLOR);
}
var tmp = this.treeRoot;
// When remving w/ 1 tree. this.treeRoot == null?
this.cmd("CreateLabel", tmpPtrID, "NextElem", this.treeRoot.x, FibonacciHeap.TMP_PTR_Y);
while (this.treeRoot != null)
{
tmp = this.treeRoot;
this.cmd("Connect", tmpPtrID,
tmp.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", tmpPtrID,
tmp.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.treeRoot = this.treeRoot.rightSib;
if (tmp.rightSib != null)
{
this.cmd("Disconnect", tmp.internalGraphicID, tmp.rightSib.internalGraphicID);
this.cmd("Disconnect", tmp.rightSib.internalGraphicID, tmp.internalGraphicID);
}
this.cmd("Step");
tmp.rightSib = null;
while(degreeArray[tmp.degree] != null)
{
this.cmd("SetEdgeHighlight", tmpPtrID, tmp.graphicID, 1);
this.cmd("SetEdgeHighlight", tmpPtrID, tmp.internalGraphicID, 1);
this.cmd("SetEdgeHighlight", degreeGraphic[tmp.degree], degreeArray[tmp.degree].graphicID, 1);
this.cmd("SetEdgeHighlight", degreeGraphic[tmp.degree], degreeArray[tmp.degree].internalGraphicID, 1);
this.cmd("Step");
this.cmd("Disconnect", tmpPtrID, tmp.graphicID);
this.cmd("Disconnect", tmpPtrID, tmp.internalGraphicID);
this.cmd("Disconnect", degreeGraphic[tmp.degree], degreeArray[tmp.degree].graphicID);
this.cmd("Disconnect", degreeGraphic[tmp.degree], degreeArray[tmp.degree].internalGraphicID);
this.cmd("SetNull", degreeGraphic[tmp.degree], 1);
var tmp2 = degreeArray[tmp.degree];
degreeArray[tmp.degree] = null
tmp = this.combineTrees(tmp, tmp2);
this.cmd("Connect", tmpPtrID,
tmp.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", tmpPtrID,
tmp.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.SetAllTreePositions(this.treeRoot, degreeArray, tmp);
this.cmd("Move", tmpPtrID, tmp.x, FibonacciHeap.TMP_PTR_Y);
this.MoveAllTrees(this.treeRoot, degreeArray, tmp);
}
this.cmd("Disconnect", tmpPtrID, tmp.graphicID);
this.cmd("Disconnect", tmpPtrID, tmp.internalGraphicID);
degreeArray[tmp.degree] = tmp;
this.cmd("SetNull", degreeGraphic[tmp.degree], 0);
this.cmd("Connect", degreeGraphic[tmp.degree],
tmp.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", degreeGraphic[tmp.degree],
tmp.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Step");
this.SetAllTreePositions(this.treeRoot, degreeArray);
this.MoveAllTrees(this.treeRoot, degreeArray);
}
this.minElement = null;
for (i = FibonacciHeap.MAX_DEGREE; i >= 0; i--)
{
if (degreeArray[i] != null)
{
degreeArray[i].rightSib = this.treeRoot;
if (this.minElement == null || this.minElement.data > degreeArray[i].data)
{
this.minElement = degreeArray[i];
}
this.treeRoot = degreeArray[i];
if (this.treeRoot.rightSib != null)
{
this.cmd("Connect", this.treeRoot.internalGraphicID,
this.treeRoot.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.treeRoot.rightSib.internalGraphicID,
this.treeRoot.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
}
}
this.cmd("Delete", degreeGraphic[i]);
this.cmd("Delete", indexID[i]);
}
if (this.minElement != null)
{
this.cmd("CreateLabel", this.minID,"Min element", this.minElement.x,FibonacciHeap.TMP_PTR_Y);
this.cmd("Connect", this.minID,
this.minElement.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
this.cmd("Connect", this.minID,
this.minElement.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
1, // Directed
""); // Label
}
this.cmd("Delete", tmpPtrID);
}
FibonacciHeap.prototype.MoveAllTrees = function(tree, treeList, tree2)
{
if (tree2 != null && tree2 != undefined)
{
this.moveTree(tree2);
}
if (tree != null)
{
this.moveTree(tree);
}
for (var i = 0; i < treeList.length; i++)
{
if (treeList[i] != null)
{
this.moveTree(treeList[i]);
}
}
this.cmd("Step");
}
FibonacciHeap.prototype.SetAllTreePositions = function(tree, treeList, tree2)
{
var leftSize = FibonacciHeap.STARTING_X;
if (tree2 != null && tree2 != undefined)
{
leftSize = this.setPositions(tree2, leftSize, FibonacciHeap.STARTING_Y); // +FibonacciHeap.NODE_WIDTH;
}
if (tree != null)
{
leftSize = this.setPositions(tree, leftSize, FibonacciHeap.STARTING_Y); // + FibonacciHeap.NODE_WIDTH;
}
for (var i = 0; i < treeList.length; i++)
{
if (treeList[i] != null)
{
leftSize = this.setPositions(treeList[i], leftSize, FibonacciHeap.STARTING_Y); // + FibonacciHeap.NODE_WIDTH;
}
}
}
FibonacciHeap.prototype.combineTrees = function(tree1, tree2)
{
if (tree2.data < tree1.data)
{
var tmp = tree2;
tree2 = tree1;
tree1 = tmp;
}
if (tree1.degree != tree2.degree)
{
return null;
}
tree2.rightSib = tree1.leftChild;
tree2.parent =tree1;
tree1.leftChild = tree2;
tree1.degree++;
if (tree1.leftChild.rightSib != null)
{
this.cmd("Disconnect", tree1.internalGraphicID, tree1.leftChild.rightSib.internalGraphicID);
this.cmd("Connect", tree1.leftChild.internalGraphicID,
tree1.leftChild.rightSib.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.3, // Curve
1, // Directed
""); // Label
this.cmd("Connect", tree1.leftChild.rightSib.internalGraphicID,
tree1.leftChild.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.3, // Curve
1, // Directed
""); // Label
}
this.cmd("Connect", tree1.internalGraphicID,
tree1.leftChild.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.15, // Curve
1, // Directed
""); // Label
this.cmd("Connect", tree1.leftChild.internalGraphicID,
tree1.internalGraphicID,
FibonacciHeap.FOREGROUND_COLOR,
0.0, // Curve
1, // Directed
""); // Label
this.cmd("SetText", tree1.degreeID, tree1.degree);
this.cmd("Connect", tree1.graphicID,
tree2.graphicID,
FibonacciHeap.FOREGROUND_COLOR,
0, // Curve
0, // Directed
""); // Label
// TODO: Add all the internal links &etc
return tree1;
}
FibonacciHeap.prototype.enableUI = function(event)
{
for (var i = 0; i < this.controls.length; i++)
{
this.controls[i].disabled = false;
}
}
FibonacciHeap.prototype.disableUI = function(event)
{
for (var i = 0; i < this.controls.length; i++)
{
this.controls[i].disabled = true;
}
}
var currentAlg;
function init()
{
var animManag = initCanvas();
currentAlg = new FibonacciHeap(animManag, canvas.width, canvas.height);
}
function BinomialNode(val, id, initialX, initialY)
{
this.data = val;
this.x = initialX;
this.y = initialY;
this.graphicID = id;
this.degree = 0;
this.leftChild = null;
this.rightSib = null;
this.parent = null;
this.internalGraphicID = -1;
this.degreeID = -1;
}