class Node {
Node parent;
Node child;
Node sibling;
int key;
int degree;
public Node(int key) {
this.key = key;
this.degree = 0;
this.child = null;
this.parent = null;
this.sibling = null;
}
}
public class BinomialHeap {
public Node head;
public BinomialHeap() {
head = null;
}
// 尋找最小關鍵字
public Node min() {
Node n = head;
Node m = null;
int min = head.key;
while (null != n) {
if (min > n.key) {
min = n.key;
m = n;
}
n = n.sibling;
}
return m;
}
// 按度的大小歸併兩個二項堆
public void merge(BinomialHeap heap) {
Node node;
Node head1 = this.head;
Node head2 = heap.head;
// 確定head
if (head1.degree < head2.degree) {
node = head1;
head1 = head.sibling;
} else {
this.head = head2;
node = heap.head;
head2 = head2.sibling;
}
// 歸併二項堆
while (head1 != null && head2 != null) {
if (head1.degree < head2.degree) {
node.sibling = head1;
node = head1;
head1 = head1.sibling;
} else {
node.sibling = head2;
node = head2;
head2 = head2.sibling;
}
}
if (head1 == null) {
node.sibling = head2;
} else {
node.sibling = head1;
}
}
// 合併二叉樹
public void link(Node big, Node small) {
big.parent = small;
big.sibling = small.child;
small.child = big;
small.degree++;
}
// 合併二項堆(把this和heap合併爲一個新的this)
public void union(BinomialHeap heap) {
// 處理空值的情況
if (null == heap.head) {
return;
}
if (null == this.head) {
this.head = heap.head;
return;
}
// 沒有空值開始合併
merge(heap);
Node pre = null;
Node x = this.head;
Node next = x.sibling;
while (null != next) {
if ((x.degree != next.degree)
|| (null != next.sibling && next.sibling.degree == x.degree)) {
pre = x;
x = next;
} else if (x.key <= next.key) {
x.sibling = next.sibling;
link(next, x);
} else {
if (null == pre) {
this.head = next;
} else {
pre.sibling = next;
}
link(x, next);
x = next;
}
next = x.sibling;
}
}
// 插入新結點
public void insert(int key) {
Node node = new Node(key);
BinomialHeap h = new BinomialHeap();
h.head = node;
union(h);
}
// 查找某結點
public Node find(int key, Node node) {
if (null == node) {
return null;
}
if (key == node.key) {
return node;
}
Node n1 = find(key, node.sibling);
Node n2 = find(key, node.child);
if (n1 != null || n2 != null) {
if (n1 != null) {
return n1;
} else {
return n2;
}
} else {
return null;
}
}
// 抽取關鍵字最小的結點
public void extract_min() {
Node min = min();
Node premin = head;
// 把最小值所在的二項樹獨立出來
if (min != head) {
while (premin.sibling != min) {
premin = premin.sibling;
}
premin.sibling = min.sibling;
} else {
head = head.sibling;
}
min.sibling = null;
// 把最小值所在的二項樹重新組織成二項堆
BinomialHeap bh = new BinomialHeap();
// 讓min脫離出來
Node child = min.child;
child.parent = null;
min.child = null;
// 反轉min的孩子使之成爲新的二項堆(這也是反轉單向鏈表的一般方法)
Node pre, cur, ne;
pre = child;
cur = child.sibling;
pre.sibling = null;
while (cur != null) {
ne = cur.sibling;
cur.parent = null;
cur.sibling = pre;
pre = cur;
cur = ne;
}
bh.head = pre;
// 分離出來的新二項堆與原來的合併
union(bh);
}
// 減小某結點的值
public void decrease_key(int key, int nkey) {
if (nkey > key) {
System.out.print("error,輸入的數比原結點的值大\n");
return;
} else {
Node n = find(key, head);
if (n == null) {
System.out.print("結點不存在\n");
return;
} else {
n.key = nkey;
Node nparent = n.parent;
while (nparent != null && n.key < nparent.key) {
int temp = n.key;
n.key = nparent.key;
nparent.key = temp;
n = nparent;
nparent = nparent.parent;
}
}
}
}
// 刪除結點
public void delete(int key) {
Node n = find(key, head);
if (n == null) {
System.out.print("結點不存在\n");
return;
} else {
decrease_key(key, -Integer.MAX_VALUE);
extract_min();
}
}
// 遍歷二項堆
public void traversal(Node node) {
if (null == node) {
return;
}
System.out.print(node.key + ",");
traversal(node.sibling);
traversal(node.child);
}
public static void main(String[] args) {
int[] E = { 0, 12, 90, 1, 85, 12, 3, 13, 49, 55, 10, 3, 31, 97, 19, 93,
41, 55, 56, 82, 2, };
BinomialHeap heap = new BinomialHeap();
// 建立二項堆
for (int i = 0; i < E.length; i++) {
heap.insert(E[i]);
}
// 遍歷
heap.traversal(heap.head);
// 查找
Node n = heap.find(87, heap.head);
System.out.println();
if (null == n) {
System.out.print("結點不存在\n");
} else
System.out.print("要找的結點值爲" + n.key + "\n");
// 輸出最小值
System.out.println("最小值爲:" + heap.min().key);
// 刪除結點
heap.delete(19);
heap.traversal(heap.head);
}
}
轉自:http://hi.baidu.com/%D0%D0%D7%DF%D4%DA%BF%D5%D6%D0/blog/item/7523d112268f0a41f819b89f.html