您的位置:首页 > 编程语言 > Java开发

java实现裴波那契堆

2016-06-13 01:55 453 查看
当时看到裴波那契堆的时候觉得没什么,后来看到图这部分的时候,发现他比较重要,于是实现以下。

package tree;

public class FibHeap {

public Node min;
public int count;

public static class Node {
protected int key;
protected Node parent;
protected Node child;
protected Node left;
protected Node right;
protected int degree;
protected boolean mark;

public Node(int key) {
this.key = key;
this.right = this.left = this;
}
}

public static void beforeInsert(Node current, Node node) {
current.left.right = node;
node.left = current.left;
current.left = node;
node.right = current;
}

public static void insert(FibHeap heap, Node node) {
node.mark = false;
if (heap.min == null) {
heap.min = node;
node.left = node.right = node;
} else {
beforeInsert(heap.min, node);
if (node.key < heap.min.key)
heap.min = node;
}
heap.count++;
}

public static FibHeap union(FibHeap heap1, FibHeap heap2) {
FibHeap heap = new FibHeap();
FibHeap other;
if (heap1.min != null) {
heap = heap1;
other = heap2;
} else if (heap2.min != null) {
heap = heap2;
other = heap1;
} else
return heap;
heap.count += other.count;
if (other.count != 0) {
Node temp1 = heap.min.left;
Node temp2 = other.min.left;
temp2.right = heap.min;
heap.min.left = temp2;
temp1.right = other.min;
other.min.right = temp1;
if (other.min.key < heap.min.key)
heap.min = other.min;
}
return heap;
}

public static Node extractMin(FibHeap heap) {
Node min = heap.min;
if (min != null) {
while (min.child != null) {
Node child = min.child;
Node right = child.right;
Node heapMinRight = heap.min.right;
heap.min.right = child;
child.left = heap.min;
heapMinRight.left = child;
child.right = heapMinRight;
child.parent = null;
heap.count++;
//child.mark = false;
if (right != child)
min.child = right;
else {
min.child = null;
break;
}
}
heap.count--;
if (min.right == min) {
heap.min = null;
} else {
heap.min.left.right = heap.min.right;
heap.min.right.left = heap.min.left;
heap.min = heap.min.right;
consolidate(heap);
}
}
return min;
}

private static void consolidate(FibHeap heap) {
int sum_degree = heap.min.degree;
Node node = heap.min.left;
if (heap.count > 1)
while (node != heap.min) {
sum_degree += node.degree;
node = node.left;
}
Node[] nodeArray = new Node[sum_degree];
A:
while (true) {
if (nodeArray[node.degree] == null) {
nodeArray[node.degree] = node;
node = node.left;
} else if (!node.equals(nodeArray[node.degree])) {
int d = node.degree;
while (nodeArray[d] != null) {
node = nodeArray[node.degree].key > node.key
? heapLink(heap, nodeArray[node.degree], node)
: heapLink(heap, node, nodeArray[node.degree]);
nodeArray[d++] = null;
}
nodeArray[d] = node;
node = node.left;
} else {
Node current = node;
node = node.left;
while (true)
if (node.equals(current))
break A;
else if (nodeArray[node.degree] == null || !node.equals(nodeArray[node.degree]))
break;
else
node = node.left;
}
}
Node min_temp = node;
heap.min = node;
heap.count = 1;
while (true) {
if (min_temp.key > node.key)
min_temp = node;
node = node.left;
if (node == heap.min)
break;
heap.count++;
}
heap.min = min_temp;
}

public static void decreaseKey(FibHeap heap, Node x, int key) throws Exception {
if (key > x.key)
throw new Exception("key must great then x.key !");
x.key = key;
Node y = x.parent;
if (y != null && x.key < y.key) {
cut(heap, x, y);
cascadingCut(heap, y);
}
if (heap.min.key < x.key)
heap.min = x;
}

private static void cut(FibHeap heap, Node x, Node y) {
x.left.right = x.right;
x.right.left = x.left;
y.degree--;
Node minRight = heap.min.right;
minRight.left = x;
heap.min.right = x;
x.left = heap.min;
x.right = minRight;
x.parent = null;
x.mark = false;
}

private static void cascadingCut(FibHeap heap, Node y) {
Node z = y.parent;
if (z != null)
if (!y.mark)
y.mark = true;
else {
cut(heap, y, z);
cascadingCut(heap, z);
}
}

public static void delete(FibHeap heap, Node node) {
try {
decreaseKey(heap,node,Integer.MIN_VALUE);
} catch (Exception e) {
}
extractMin(heap);
}
private static Node heapLink(FibHeap heap, Node other, Node tempNode) {
other.left.right = other.right;
other.right.left = other.left;
other.parent = tempNode;
tempNode.child.right.left = other;
tempNode.child.right = other;
other.right = tempNode.child.right;
other.left = tempNode;
tempNode.degree++;
other.mark = false;
return tempNode;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: