fibonacciheap.java
来自「JAVA图论的算法包。用过觉得还不错」· Java 代码 · 共 612 行 · 第 1/2 页
JAVA
612 行
}
// size
/**
* Joins two Fibonacci heaps into a new one. No heap consolidation is
* performed at this time. The two root lists are simply joined together.
*
* <p>Running time: O(1) actual</p>
*
* @param h1 first heap
* @param h2 second heap
*
* @return new heap containing h1 and h2
*/
public static <T> FibonacciHeap<T> union(
FibonacciHeap<T> h1,
FibonacciHeap<T> h2)
{
FibonacciHeap<T> h = new FibonacciHeap<T>();
if ((h1 != null) && (h2 != null)) {
h.minNode = h1.minNode;
if (h.minNode != null) {
if (h2.minNode != null) {
h.minNode.right.left = h2.minNode.left;
h2.minNode.left.right = h.minNode.right;
h.minNode.right = h2.minNode;
h2.minNode.left = h.minNode;
if (h2.minNode.key < h1.minNode.key) {
h.minNode = h2.minNode;
}
}
} else {
h.minNode = h2.minNode;
}
h.nNodes = h1.nNodes + h2.nNodes;
}
return h;
}
// union
/**
* Creates a String representation of this Fibonacci heap.
*
* @return String of this.
*/
public String toString()
{
if (minNode == null) {
return "FibonacciHeap=[]";
}
// create a new stack and put root on it
Stack<FibonacciHeapNode<T>> stack = new Stack<FibonacciHeapNode<T>>();
stack.push(minNode);
StringBuffer buf = new StringBuffer(512);
buf.append("FibonacciHeap=[");
// do a simple breadth-first traversal on the tree
while (!stack.empty()) {
FibonacciHeapNode<T> curr = stack.pop();
buf.append(curr);
buf.append(", ");
if (curr.child != null) {
stack.push(curr.child);
}
FibonacciHeapNode<T> start = curr;
curr = curr.right;
while (curr != start) {
buf.append(curr);
buf.append(", ");
if (curr.child != null) {
stack.push(curr.child);
}
curr = curr.right;
}
}
buf.append(']');
return buf.toString();
}
// toString
/**
* Performs a cascading cut operation. This cuts y from its parent and then
* does the same for its parent, and so on up the tree.
*
* <p>Running time: O(log n); O(1) excluding the recursion</p>
*
* @param y node to perform cascading cut on
*/
protected void cascadingCut(FibonacciHeapNode<T> y)
{
FibonacciHeapNode<T> z = y.parent;
// if there's a parent...
if (z != null) {
// if y is unmarked, set it marked
if (!y.mark) {
y.mark = true;
} else {
// it's marked, cut it from parent
cut(y, z);
// cut its parent as well
cascadingCut(z);
}
}
}
// cascadingCut
protected void consolidate()
{
int arraySize =
((int) Math.floor(Math.log(nNodes) * oneOverLogPhi)) + 1;
List<FibonacciHeapNode<T>> array =
new ArrayList<FibonacciHeapNode<T>>(arraySize);
// Initialize degree array
for (int i = 0; i < arraySize; i++) {
array.add(null);
}
// Find the number of root nodes.
int numRoots = 0;
FibonacciHeapNode<T> x = minNode;
if (x != null) {
numRoots++;
x = x.right;
while (x != minNode) {
numRoots++;
x = x.right;
}
}
// For each node in root list do...
while (numRoots > 0) {
// Access this node's degree..
int d = x.degree;
FibonacciHeapNode<T> next = x.right;
// ..and see if there's another of the same degree.
for (;;) {
FibonacciHeapNode<T> y = array.get(d);
if (y == null) {
// Nope.
break;
}
// There is, make one of the nodes a child of the other.
// Do this based on the key value.
if (x.key > y.key) {
FibonacciHeapNode<T> temp = y;
y = x;
x = temp;
}
// FibonacciHeapNode<T> y disappears from root list.
link(y, x);
// We've handled this degree, go to next one.
array.set(d, null);
d++;
}
// Save this node for later when we might encounter another
// of the same degree.
array.set(d, x);
// Move forward through list.
x = next;
numRoots--;
}
// Set min to null (effectively losing the root list) and
// reconstruct the root list from the array entries in array[].
minNode = null;
for (int i = 0; i < arraySize; i++) {
FibonacciHeapNode<T> y = array.get(i);
if (y == null) {
continue;
}
// We've got a live one, add it to root list.
if (minNode != null) {
// First remove node from root list.
y.left.right = y.right;
y.right.left = y.left;
// Now add to root list, again.
y.left = minNode;
y.right = minNode.right;
minNode.right = y;
y.right.left = y;
// Check if this is a new min.
if (y.key < minNode.key) {
minNode = y;
}
} else {
minNode = y;
}
}
}
// consolidate
/**
* The reverse of the link operation: removes x from the child list of y.
* This method assumes that min is non-null.
*
* <p>Running time: O(1)</p>
*
* @param x child of y to be removed from y's child list
* @param y parent of x about to lose a child
*/
protected void cut(FibonacciHeapNode<T> x, FibonacciHeapNode<T> y)
{
// remove x from childlist of y and decrement degree[y]
x.left.right = x.right;
x.right.left = x.left;
y.degree--;
// reset y.child if necessary
if (y.child == x) {
y.child = x.right;
}
if (y.degree == 0) {
y.child = null;
}
// add x to root list of heap
x.left = minNode;
x.right = minNode.right;
minNode.right = x;
x.right.left = x;
// set parent[x] to nil
x.parent = null;
// set mark[x] to false
x.mark = false;
}
// cut
/**
* Make node y a child of node x.
*
* <p>Running time: O(1) actual</p>
*
* @param y node to become child
* @param x node to become parent
*/
protected void link(FibonacciHeapNode<T> y, FibonacciHeapNode<T> x)
{
// remove y from root list of heap
y.left.right = y.right;
y.right.left = y.left;
// make y a child of x
y.parent = x;
if (x.child == null) {
x.child = y;
y.right = y;
y.left = y;
} else {
y.left = x.child;
y.right = x.child.right;
x.child.right = y;
y.right.left = y;
}
// increase degree[x]
x.degree++;
// set mark[y] false
y.mark = false;
}
// link
}
// FibonacciHeap
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?