// Merge two subtrees together, returning the one that came out on top.
    // For a pairing heap, merging consists of adding the larger node
    // to the sub list of the smaller.
    private HeapNode <T> merge(HeapNode <T> a, HeapNode <T> b)
    {
        if (compare(a.getNode(), b.getNode()) <= 0)        // a <= b (swap a and b)
        {
            HeapNode <T> tmp = a;
            a = b; b = tmp;
        }


        // Here we assume that a > b, therefore a is added to b's children

        // Remove a from any child list it might be in.
        a.extract();

        // Link a into b's child list
        b.addChild(a);

        return(b);
    }
    // Delete the mininum node, and return it. This is where the log n
    // magic happens. Pairs the sub-list together, then sweeps up the pairs
    // into one tree again.
    public T deleteMin()
    {
        if (isEmpty())
        {
            return(default(T));
        }

        // NOTE: the final_cast is needed so the user can modify his own data.
        T            ret = top.getNode();
        HeapNode <T> newtop, i, j;

        if (top.getChild() == null)         // Only one element in heap
        {
            top = null;
            size--;
            return(ret);
        }

        // First of two passes: combine pairs of roots together, from
        // left to right.
        i = top.getChild();

        // Note, end condition is too complicated for more generalized loops
        while (true)
        {                                  // i is the first, j is the second
            if ((j = i.getNext()) == null) // If i is the odd man out (no partner j)
            {
                break;
            }

            if (i == merge(i, j))        // i came out on top
            {
                if (i.getNext() == null) // i is now the last in the loop
                {
                    break;
                }

                i = i.getNext();
            }
            else  // j came out on top
            {
                if (j.getNext() == null)                // j is the last in the loop
                {
                    i = j;                      // As a set up for the next pass
                    break;
                }

                i = j.getNext();
            }
        }

        // Iterate the other way, combining each new tree with the rightmost
        newtop = i;
        j      = i.getPrev();

        while (j != null)
        {
            newtop = merge(newtop, j);
            j      = newtop.getPrev();
        }

        top = newtop;

        size--;

        return(ret);
    }
예제 #3
0
    public T pop()
    {
        if (root == null)
        {
            return(default(T));
        }

        Queue <HeapNode <T> > q    = new Queue <HeapNode <T> >();
        HeapNode <T>          curr = root;
        HeapNode <T>          prev = null;

        while (curr != null)
        {
            HeapNode <T> l = curr.getLeft();
            q.Enqueue(l);

            HeapNode <T> r = curr.getRight();
            q.Enqueue(r);

            prev = curr;
            curr = q.Dequeue();
        }

        //case where root is the only one
        //handle it here to avoid null pointers below
        if (prev.Equals(root))
        {
            root = null;
            return(prev.getNode());
        }

        //set last element in tree to root node
        //set roots left and right to new root left and right
        prev.setLeft(root.getLeft());
        prev.setRight(root.getRight());

        //set new root parents to this
        if (prev.getLeft() != null)
        {
            prev.getLeft().setParent(prev);
        }
        if (prev.getRight() != null)
        {
            prev.getRight().setParent(prev);
        }

        //set prev's old parent's left or right branch to null
        if (prev.getParent().getLeft().Equals(prev))
        {
            prev.getParent().setLeft(null);
        }
        else if (prev.getParent().getRight().Equals(prev))
        {
            prev.getParent().setRight(null);
        }

        //set prev parent to null since it will be the root
        prev.setParent(null);

        HeapNode <T> popVal = root;

        root = prev;

        //place prev in its correct place
        //root.sort();
        root = root.sortChild();

        //completely disconnect popped value from tree
        popVal.setParent(null);
        popVal.setLeft(null);
        popVal.setRight(null);

        return(popVal.getNode());
    }