java实现裴波那契堆

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

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;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值