1 public class FibHeap 2 { 3 private FibNode min; 4 5 private int count; 6 7 private FibNode root; 8 9 10 public FibHeap() 11 { 12 root = new FibNode(); 13 root.left = root; 14 root.right = root; 15 } 16 17 /* 18 * 返回最小节点 19 */ 20 public FibNode min() 21 { 22 return min; 23 } 24 25 /* 26 * 删除节点 27 */ 28 public void delete(FibNode node) 29 { 30 decereaseKey(node, Integer.MIN_VALUE); 31 extractMin(); 32 } 33 34 /* 35 * 减小某结点的值 36 */ 37 public void decereaseKey(FibNode node, int k) 38 { 39 if (node.key < k) { 40 throw new RuntimeException("new key is greater than current key"); 41 } 42 43 node.key = k; 44 FibNode parent = node.parent; 45 if (parent != null && node.key < parent.key) { 46 cut(node, parent); 47 cascadingCut(parent); 48 } 49 50 if (node.key < min.key) min = node; 51 } 52 53 /* 54 * 剔除node节点并执行insertRoot 55 */ 56 public void cut(FibNode node, FibNode parent) 57 { 58 node.left.right = node.right; 59 node.right.left = node.left; 60 parent.degree--; 61 62 insertRoot(node); 63 node.parent = null; 64 node.mark = false; 65 } 66 67 /* 68 * ?????? 69 */ 70 public void cascadingCut(FibNode node) 71 { 72 FibNode parent = node.parent; 73 if (parent != null) { 74 if (!node.mark) { 75 node.mark = true; 76 } 77 else { 78 cut(node, parent); 79 cascadingCut(parent); 80 } 81 } 82 } 83 84 /* 85 * 抽取最小关键子节点 86 */ 87 public FibNode extractMin() 88 { 89 FibNode node = min; 90 if (node != null) { 91 92 if (node.degree != 0) { 93 FibNode child = node.child; 94 FibNode next = child; 95 96 do { 97 next.parent = null; 98 next = next.right; 99 } 100 while (child != next); 101 102 node.left.right = child.right; 103 child.right.left = node.left; 104 node.right.left = child; 105 child.right = node.right; 106 } 107 else { 108 node.left.right = node.right; 109 node.right.left = node.left; 110 } 111 112 if (node == node.right) { 113 min = null; 114 } 115 else { 116 min = min.right; 117 consolidate(); 118 } 119 count--; 120 } 121 return node; 122 } 123 124 /* 125 * 输出根节点 126 */ 127 public void displayRoot() 128 { 129 FibNode node = root.right; 130 while (node != root) { 131 System.out.println(node.key); 132 node = node.right; 133 } 134 } 135 136 /* 137 * 合并 138 */ 139 public void consolidate() 140 { 141 FibNode[] array = new FibNode[(int) (Math.log(count) / Math.log(2)) + 1]; 142 143 FibNode node = root.right; 144 while (node != root) { 145 FibNode nodex = node; 146 node = node.right; 147 int degree = nodex.degree; 148 149 while (array[degree] != null) { 150 FibNode nodey = array[degree]; 151 if (nodex.key > nodey.key) { 152 // swap 153 FibNode temp = nodex; 154 nodex = nodey; 155 nodey = temp; 156 } 157 link(nodey, nodex); 158 array[degree++] = null; 159 } 160 array[degree] = nodex; 161 } 162 163 min = null; 164 for (int i = 0; i < array.length; i++) { 165 if (array[i] != null) { 166 if (min == null || array[i].key < min.key) { 167 min = array[i]; 168 } 169 } 170 } 171 } 172 173 /* 174 * 连接节点 175 */ 176 public void link(FibNode node, FibNode parent) 177 { 178 node.left.right = node.right; 179 node.right.left = node.left; 180 node.parent = parent; 181 182 if (parent.degree == 0) { 183 parent.child = node; 184 node.left = node; 185 node.right = node; 186 } 187 else { 188 node.left = parent.child.left; 189 parent.child.left.right = node; 190 node.right = parent.child; 191 parent.child.left = node; 192 } 193 194 parent.degree++; 195 node.mark = false; 196 } 197 198 /* 199 * 插入节点 200 */ 201 public void insert(FibNode node) 202 { 203 node.degree = 0; 204 node.parent = null; 205 node.child = null; 206 node.left = node; 207 node.right = node; 208 node.mark = false; 209 210 insertRoot(node); 211 212 if (min == null || node.key < min.key) { 213 min = node; 214 } 215 count++; 216 } 217 218 /* 219 * 合并两个堆 220 */ 221 public void union(FibHeap heap) 222 { 223 if (heap.count == 0) return; 224 225 FibNode node = heap.root; 226 node.right.left = root.left; 227 root.left.right = node.right; 228 node.left.right = root; 229 root.left.left = node; 230 231 if (min == null || heap.min.key < min.key) { 232 min = heap.min; 233 } 234 count += heap.count; 235 } 236 237 /* 238 * 插入Root节点 239 */ 240 private void insertRoot(FibNode node) 241 { 242 /* 243 * left node root 244 * O-----O-----O 245 */ 246 247 node.left = root.left; 248 root.left.right = node; 249 node.right = root; 250 root.left = node; 251 } 252 253 static class FibNode 254 { 255 FibNode child; 256 257 FibNode left; 258 259 FibNode right; 260 261 FibNode parent; 262 263 int degree = 0; 264 265 boolean mark = false; 266 267 int key; 268 269 270 public FibNode() {} 271 272 public FibNode(int key) 273 { 274 this.key = key; 275 } 276 } 277 278 public static void main(String[] args) 279 { 280 FibHeap fh = new FibHeap(); 281 282 int[] keys = { 9, 10, 5, 14, 12, 13, 8, 3 }; 283 for (int i = 0; i < keys.length; i++) { 284 fh.insert(new FibNode(keys[i])); 285 } 286 287 FibHeap fh2 = new FibHeap(); 288 289 int[] keys2 = { 3,7,2,7,9,14,66}; 290 for (int i = 0; i < keys2.length; i++) { 291 FibNode fn=new FibNode(); 292 fh2.insert(new FibNode(keys2[i])); 293 } 294 295 fh.union(fh2); 296 System.out.println(fh.min().key); 297 298 fh.displayRoot(); 299 System.out.println("min:" + fh.extractMin().key); 300 System.out.println("min:" + fh.extractMin().key); 301 System.out.println("min:" + fh.extractMin().key); 302 303 fh.delete(fh.min()); 304 System.out.println(fh.min().key); 305 } 306 }