数据结构(Java)——优先队列和堆

在这里我不得不感叹《算法导论》绝对是算法数据结构经典中的经典!作为一个学习入门的人,对此书实在是敬佩不已。语言凝练,表达清楚,字字珠玑。
———Paul Zhang. 2015.11.26

1.堆

1.1堆的定义

堆就是具有两个附加属性的二叉树。
【1】它是一棵完全树;
【2】对每一结点,它小于和等于其左孩子和右孩子。
上述定义描述的是最小堆。一个堆也可以是最大堆,其中结点大于或者小于它的左右孩子。

1.2堆ADT定义

堆UML设计
 堆ADT-UML设计
Java源码

package ds.java.ch12.heapImpl;

import java.util.Iterator;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月22日 上午10:51:51
 * @description 二叉树的ADT
 */
public interface BinaryTreeADT<T> {

    /**
     * 获取根部元素
     * 
     * @return
     */
    public T getRootElement();

    /**
     * 判断是否是空树
     * 
     * @return true if this binary tree is empty, false otherwise
     */
    public boolean isEmpty();

    /**
     * 返回树中元素的个数
     * 
     * @return the number of elements in the tree
     */
    public int size();

    /**
     *判定二叉树中是否存在当前的元素
     * 
     * @param targetElement
     *            the element being sought in the tree
     * @return true if the tree contains the target element
     */
    public boolean contains(T targetElement);

    /**
     *在二叉树中查找响应的元素
     * 
     * @param targetElement
     *            the element being sought in the tree
     * @return a reference to the specified element
     */
    public T find(T targetElement);

    /**
     *输出二叉树
     * 
     * @return a string representation of the binary tree
     */
    public String toString();

    /**
     *返回二叉树的迭代器
     * 
     * @return an iterator over the elements of this binary tree
     */
    public Iterator<T> iterator();

    /**
     * Returns an iterator that represents an inorder traversal on this binary
     * tree.
     * 
     * @return an iterator over the elements of this binary tree
     */
    public Iterator<T> iteratorInOrder();

    /**
     * Returns an iterator that represents a preorder traversal on this binary
     * tree.
     * 
     * @return an iterator over the elements of this binary tree
     */
    public Iterator<T> iteratorPreOrder();

    /**
     * Returns an iterator that represents a postorder traversal on this binary
     * tree.
     * 
     * @return an iterator over the elements of this binary tree
     */
    public Iterator<T> iteratorPostOrder();

    /**
     * Returns an iterator that represents a levelorder traversal on the binary
     * tree.
     * 
     * @return an iterator over the elements of this binary tree
     */
    public Iterator<T> iteratorLevelOrder();

}
package ds.java.ch12.heapImpl;
/** 
 * @author LbZhang
 * @version 创建时间:2015年11月29日 下午7:26:38 
 * @description 堆ADT
 * 有序 完全二叉树
 */
public interface HeapADT<T> extends BinaryTreeADT<T> {
    /**
     * 添加元素操作,将给定的元素添加到堆的恰当位置处,且维持该堆的完全性属性和有序属性。
     * 如果该元素Comparable的,该方法将抛出一个ClassCastException异常。
     * @param obj
     * 关键概念:
     *  addElement方法将给定的Comparable元素添加到堆的恰当位置处,且维持该堆的完全属性和有序属性。
     *  因为一个堆是完全树,所以对插入新的结点而言 ,只存在一个正确的位置,且它要么是h层左边的下一个空位置,
     *  要么实在h+1层左边的第一个位置(如果h层是满层的话)。
     *  一旦将新结点定位到正确位置,就必须考虑排序属性。为此我们只需将该值与双亲值进行比较,如果新结点小于
     *  其双亲则将他们互换。我们沿着树向上继续这一过程,直至该新值要么是大于其双亲要么是位于该堆的根处。
     *  
     */
    public void addElement(T obj);
    /**
     * removeMin方法将删除最小堆中的最小元素并返回它。由于最小元素是存储在最小堆的根处的,所以我们需要返回存储
     * 在根处的元素并用堆中的另一元素替换它,与addElement操作一样,要维持该树的完全性那么只有一个能替换根的合法
     * 元素,且它是存储在最末一片叶子上的元素。
     * 
     * 一旦存储在最末一片叶子中的元素被移动到了根处,则必须对该堆进行重排序以维持该堆的排序属性。这一目标实现的方式,
     * 将该根元素与其较小的孩子进行比较,且如果孩子更小则将它们互换。 沿着树向下继续这一过程,直至该元素要么位于某一
     * 叶子中,要么比它的两个孩子都小。 显示了删除最小元素然后重新对树排序的过程。
     * @return  
     */
    public T removeMin();
    /**
     * 返回一个指向该最小堆中的最小元素的引用。由于该元素总是存储在该树的根处,
     * 所以实现这一方法只需要通过返回存储根处的元素即可。
     * @return
     */
    public T findMin();

}

2.堆的数组实现

package ds.java.ch12.heapImpl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import ds.java.ch12.exceptions.ElementNotFoundException;
import ds.java.ch12.exceptions.EmptyCollectionException;


/** 
 * @author LbZhang
 * @version 创建时间:2015年11月30日 上午10:44:08 
 * @description 类说明
 */
public class ArrayBinaryTree<T> implements BinaryTreeADT<T>, Iterable<T> {

    private static final int DEFAULT_CAPACITY = 50;

    protected int count;
    protected T[] tree;//持有数组用于实现堆
    protected int modCount;

    public ArrayBinaryTree(){
        count = 0;
        tree = (T[])new Object[DEFAULT_CAPACITY];
    }

    public ArrayBinaryTree(T element){
        count = 1;
        tree = (T[])new Object[DEFAULT_CAPACITY];
        tree[0] = element;
    }

    protected void expandCapacity(){
        tree=Arrays.copyOf(tree, tree.length*2);
    }

    @Override
    public T getRootElement() throws EmptyCollectionException{
        if(isEmpty()){
            throw new EmptyCollectionException("ArrayBinaryTree");
        }
        return tree[0];
    }

    @Override
    public boolean isEmpty() {
        return count==0;
    }

    @Override
    public int size() {
        return count;
    }

    @Override
    public boolean contains(T targetElement) {
        T temp;
        boolean found = false;

        try{
            temp = find(targetElement);
            found = true;
        }catch(Exception ElementNotFoundException){
            found = false;
        }

        return found;
    }

    @Override
    public T find(T targetElement) throws ElementNotFoundException{

        T temp = null;
        boolean found = false;

        for(int i=0;i<tree.length;i++){
            if(tree[i]!=null){
                if(targetElement.equals(tree[i])){
                    found = true;
                    temp=tree[i];
                }

            }
        }

        if(!found){
            throw new ElementNotFoundException("ArrayBinaryTree");
        }

        return temp;
    }

    @Override
    public String toString() {
        ArrayList<T> tempList = new ArrayList<T>();
        ///用于临时存储连理获取的对象的引用的队列
        inOrder(0,tempList);
        return tempList.toString();
    }

    @Override
    public Iterator<T> iterator() {
        return this.iteratorInOrder();
    }

    @Override
    public Iterator<T> iteratorInOrder() {
        ArrayList<T> tempList = new ArrayList<>();
        inOrder(0, tempList);
        return new TreeIterator(tempList.iterator());
    }

    protected void inOrder(int root,ArrayList<T> tempList){
        if(root<tree.length){
            if(tree[root]!=null){
                inOrder(root*2+1, tempList);
                tempList.add(tree[root]);
                inOrder(root*2+2, tempList);
            }
        }
    }

    @Override
    public Iterator<T> iteratorPreOrder() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Iterator<T> iteratorPostOrder() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Iterator<T> iteratorLevelOrder() {
        // TODO Auto-generated method stub
        return null;
    }


    /**
     * 自定义一个TreeIterator类
     * @author MrLBZ
     *
     */
    private class TreeIterator implements Iterator<T>
    {
        private int expectedModCount;
        private Iterator<T> iter;

        public TreeIterator(Iterator<T> iter)
        {
            this.iter = iter;
            expectedModCount = modCount;
        }

        /**
         * Returns true if this iterator has at least one more element
         * to deliver in the iteration.
         *
         * @return  true if this iterator has at least one more element to deliver
         *          in the iteration
         * @throws  ConcurrentModificationException if the collection has changed
         *          while the iterator is in use
         */
        public boolean hasNext() throws ConcurrentModificationException
        {
            if (!(modCount == expectedModCount))
                throw new ConcurrentModificationException();

            return (iter.hasNext());
        }

        /**
         * Returns the next element in the iteration. If there are no
         * more elements in this iteration, a NoSuchElementException is
         * thrown.
         *
         * @return the next element in the iteration
         * @throws NoSuchElementException if the iterator is empty
         */
        public T next() throws NoSuchElementException
        {
            if (hasNext())
                return (iter.next());
            else 
                throw new NoSuchElementException();
        }

        /**
         * The remove operation is not supported.
         * 
         * @throws UnsupportedOperationException if the remove operation is called
         */
        public void remove()
        {
            throw new UnsupportedOperationException();
        }
    }

}
package ds.java.ch12.heapImpl;

import ds.java.ch11.exceptions.EmptyCollectionException;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月30日 下午3:00:26
 * @description 类说明
 */
public class ArrayHeap<T> extends ArrayBinaryTree<T> implements HeapADT<T> {

    public ArrayHeap() {
        super();
    }

    @Override
    public void addElement(T obj) {
        if (count == tree.length) {
            expandCapacity();
        }
        tree[count] = obj;
        count++;
        modCount++;

        if (count > 1) {
            // 检查当前的插入
            heapModifyAdd();
        }
    }

    private void heapModifyAdd() {
        T temp;
        int next = count - 1;
        temp = tree[next];
        while (next != 0
                && (((Comparable) temp).compareTo(tree[(next - 1) / 2]) < 0)) {
            tree[next] = tree[(next - 1) / 2];
            next = (next - 1) / 2;
        }
        tree[next] = temp;
    }

    @Override
    public T removeMin() throws EmptyCollectionException {
        if (isEmpty()) {
            throw new EmptyCollectionException("ArrayHeap");
        }
        T minElement = tree[0];
        tree[0] = tree[count - 1];
        heapModifyRemove();
        count--;//当前的空白位置--
        modCount--;
        return minElement;
    }

    /**
     * //删除修改堆结构
     */
    private void heapModifyRemove() {
        T temp;
        // 开始的三个结点
        int node = 0;
        int left = 1;
        int right = 2;

        int next;

        if ((tree[left] == null) && (tree[right] == null))
            next = count;
        else if (tree[right] == null)
            next = left;//右边为null
        else if (((Comparable) tree[left]).compareTo(tree[right]) < 0)
            next = left;
        else
            next = right;
        temp = tree[node];//临时存储  一个需要迁移的位置


        while ((next < count)
                && (((Comparable) tree[next]).compareTo(temp) < 0)) {
            tree[node] = tree[next];
            node = next;
            left = 2 * node + 1;
            right = 2 * (node + 1);
            if ((tree[left] == null) && (tree[right] == null))
                next = count;
            else if (tree[right] == null)
                next = left;
            else if (((Comparable) tree[left]).compareTo(tree[right]) < 0)
                next = left;
            else
                next = right;
        }
        //最后放在node
        tree[node] = temp;

    }

    @Override
    public T findMin() {
        if (isEmpty())
            throw new EmptyCollectionException("ArrayHeap");
        return tree[0];
    }

}

3.堆的无序链表实现

package ds.java.ch12.heapImpl;

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import ds.java.ch05.queueImpl.EmptyCollectionException;
import ds.java.ch06.listImpl.ArrayUnorderedList;
import ds.java.ch06.listImpl.ElementNotFoundException;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月22日 上午11:04:36
 * @description 二叉树的构建
 */
public class LinkedBinaryTree<T> implements Iterable<T>, BinaryTreeADT<T> {

    // 根结点的设置
    protected BinaryTreeNode<T> root;//gen结点
    protected int modCount;// 修改标记 用于Iterator中使用

    // protected int sizeOfLTree;

    /**
     * 无参构造方法
     */
    public LinkedBinaryTree() {
        root = null;
    }

    public LinkedBinaryTree(T element) {
        root = new BinaryTreeNode<T>(element);
    }

    public LinkedBinaryTree(BinaryTreeNode<T> ltn) {
        this.root = ltn;
    }

    public LinkedBinaryTree(T element, LinkedBinaryTree<T> left,
            LinkedBinaryTree<T> right) {
        root = new BinaryTreeNode<T>(element);
        root.setLeft(left.root);
        root.setRight(right.root);
    }

    /**
     * 获取根节点
     * 
     * @return
     */
    public BinaryTreeNode<T> getRootNode() throws EmptyCollectionException {
        if (isEmpty()) {
            throw new EmptyCollectionException("BinaryTreeNode ");
        }
        return root;
    }

    /**
     * Returns the left subtree of the root of this tree.
     * 
     * @return a link to the right subtree of the tree
     */
    public LinkedBinaryTree<T> getLeft() {
        return new LinkedBinaryTree(this.root.getLeft());
        // To be completed as a Programming Project
    }

    /**
     * Returns the right subtree of the root of this tree.
     * 
     * @return a link to the right subtree of the tree
     */
    public LinkedBinaryTree<T> getRight() {
        return new LinkedBinaryTree(this.root.getRight());
    }

    /**
     * Returns the height of this tree.
     * 
     * @return the height of the tree
     */
    public int getHeight() {
        return 0;
        // To be completed as a Programming Project
    }

    /**
     * Returns the height of the specified node.
     * 
     * @param node
     *            the node from which to calculate the height
     * @return the height of the tree
     */
    private int height(BinaryTreeNode<T> node) {
        return 0;
        // To be completed as a Programming Project
    }

    @Override
    public T getRootElement() throws EmptyCollectionException {
        if (root.getElement().equals(null)) {
            throw new EmptyCollectionException("BinaryTreeNode ");
        }
        return root.getElement();
    }

    @Override
    public boolean isEmpty() {
        return (root == null);
    }

    /**
     * 返回的是当前结点孩子结点的个数
     */
    @Override
    public int size() {

        int size = 0;
        if(root.getLeft()!=null){
            size+=1;
        }
        if(root.getRight()!=null){
            size+=1;
        }

        return size;
    }

    @Override
    public boolean contains(T targetElement) {
        return false;
    }

    @Override
    public T find(T targetElement) {
        // 获取当前元素
        BinaryTreeNode<T> current = findNode(targetElement, root);

        if (current == null)
            throw new ElementNotFoundException("LinkedBinaryTree");

        return (current.getElement());
    }

    private BinaryTreeNode<T> findNode(T targetElement, BinaryTreeNode<T> next) {
        if (next == null)
            return null;

        if (next.getElement().equals(targetElement))
            return next;
        // 递归调用
        BinaryTreeNode<T> temp = findNode(targetElement, next.getLeft());

        if (temp == null)
            temp = findNode(targetElement, next.getRight());

        return temp;
    }

    @Override
    public Iterator<T> iteratorInOrder() {
        ArrayUnorderedList<T> tempList = new ArrayUnorderedList<T>();
        inOrder(root, tempList);
        return new TreeIterator(tempList.iterator());
    }

    /**
     * Performs a recursive inorder traversal. 中根遍历
     * 
     * @param node
     *            the node to be used as the root for this traversal
     * @param tempList
     *            the temporary list for use in this traversal
     */
    protected void inOrder(BinaryTreeNode<T> node,
            ArrayUnorderedList<T> tempList) {
        if (node != null) {
            inOrder(node.getLeft(), tempList);
            tempList.addToRear(node.getElement());
            inOrder(node.getRight(), tempList);
        }
    }

    /**
     * Performs an preorder traversal on this binary tree by calling an
     * overloaded, recursive preorder method that starts with the root.
     * 
     * @return a pre order iterator over this tree
     */
    @Override
    public Iterator<T> iteratorPreOrder() {
        ArrayUnorderedList<T> tempList = new ArrayUnorderedList<T>();
        preOrder(root, tempList);
        return new TreeIterator(tempList.iterator());
    }

    /**
     * Performs a recursive preorder traversal.
     * 
     * @param node
     *            the node to be used as the root for this traversal
     * @param tempList
     *            the temporary list for use in this traversal
     */
    private void preOrder(BinaryTreeNode<T> node, ArrayUnorderedList<T> tempList) {
        if (node != null) {
            tempList.addToRear(node.getElement());
            inOrder(node.getLeft(), tempList);

            inOrder(node.getRight(), tempList);
        }

    }

    /**
     * Performs an postorder traversal on this binary tree by calling an
     * overloaded, recursive postorder method that starts with the root.
     * 
     * @return a post order iterator over this tree
     */
    @Override
    public Iterator<T> iteratorPostOrder() {
        ArrayUnorderedList<T> tempList = new ArrayUnorderedList<T>();
        postOrder(root, tempList);
        return new TreeIterator(tempList.iterator());
    }

    /**
     * Performs a recursive postorder traversal.
     * 
     * @param node
     *            the node to be used as the root for this traversal
     * @param tempList
     *            the temporary list for use in this traversal
     */
    private void postOrder(BinaryTreeNode<T> node,
            ArrayUnorderedList<T> tempList) {

        if (node != null) {
            tempList.addToRear(node.getElement());
            inOrder(node.getLeft(), tempList);

            inOrder(node.getRight(), tempList);
        }

    }

    @Override
    public Iterator<T> iteratorLevelOrder() {
        ArrayUnorderedList<BinaryTreeNode<T>> nodes = new ArrayUnorderedList<BinaryTreeNode<T>>();
        ArrayUnorderedList<T> tempList = new ArrayUnorderedList<T>();
        BinaryTreeNode<T> current;

        nodes.addToRear(root);

        while (!nodes.isEmpty()) {
            current = nodes.removeFirst();

            if (current != null) {
                tempList.addToRear(current.getElement());
                if (current.getLeft() != null)
                    nodes.addToRear(current.getLeft());
                if (current.getRight() != null)
                    nodes.addToRear(current.getRight());
            } else
                tempList.addToRear(null);
        }

        return new TreeIterator(tempList.iterator());
    }

    @Override
    public Iterator<T> iterator() {
        return iteratorInOrder();
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return super.toString();
    }

    /**
     * Inner class to represent an iterator over the elements of this tree
     */
    private class TreeIterator implements Iterator<T> {
        private int expectedModCount;
        private Iterator<T> iter;

        /**
         * Sets up this iterator using the specified iterator.
         * 
         * @param iter
         *            the list iterator created by a tree traversal
         */
        public TreeIterator(Iterator<T> iter) {
            this.iter = iter;
            expectedModCount = modCount;
        }

        /**
         * Returns true if this iterator has at least one more element to
         * deliver in the iteration.
         * 
         * @return true if this iterator has at least one more element to
         *         deliver in the iteration
         * @throws ConcurrentModificationException
         *             if the collection has changed while the iterator is in
         *             use
         */
        public boolean hasNext() throws ConcurrentModificationException {
            if (!(modCount == expectedModCount))
                throw new ConcurrentModificationException();

            return (iter.hasNext());
        }

        /**
         * Returns the next element in the iteration. If there are no more
         * elements in this iteration, a NoSuchElementException is thrown.
         * 
         * @return the next element in the iteration
         * @throws NoSuchElementException
         *             if the iterator is empty
         */
        public T next() throws NoSuchElementException {
            if (hasNext())
                return (iter.next());
            else
                throw new NoSuchElementException();
        }

        /**
         * The remove operation is not supported.
         * 
         * @throws UnsupportedOperationException
         *             if the remove operation is called
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}
package ds.java.ch12.heapImpl;

import ds.java.ch12.exceptions.EmptyCollectionException;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月30日 下午8:56:51
 * @description 类说明
 */
public class LinkedHeap<T> extends LinkedBinaryTree<T> implements HeapADT<T> {

    public HeapNode<T> lastNode;

    public LinkedHeap() {
        super();
    }

    @Override
    public void addElement(T obj) {
        // 一个堆结点
        HeapNode<T> node = new HeapNode<T>(obj);

        if (root == null)
            root = node;// 如果为空 就把root指向当前的结点
        else {
            // 获取父结点 把需要添加的父结点返回
            HeapNode<T> nextParent = getNextParentAdd();

            if (nextParent.getLeft() == null)
                nextParent.setLeft(node);
            else
                nextParent.setRight(node);

            node.setParent(nextParent);
        }

        lastNode = node;// 最后的结点的引用
        modCount++;

        if (size() > 1)
            heapifyAdd();

    }

    /**
     * 添加修改当前堆
     */
    private void heapifyAdd() {
        T temp;
        // 获取最后一个结点
        HeapNode<T> next = lastNode;

        // 临时保存
        temp = next.getElement();

        // 如果不是root结点而且小于当前的结点的父结点就进行循环
        while ((next != root)
                && (((Comparable) temp)
                        .compareTo(next.getParent().getElement()) < 0)) {

            next.setElement(next.getParent().getElement());
            next = next.parent;
        }
        next.setElement(temp);// 放置到最后的结点

    }

    /**
     * 获取当前需要添加位置的结点的父结点
     * 
     * @return
     */
    private HeapNode<T> getNextParentAdd() {

        HeapNode<T> result = lastNode;// 当前的空白结点

        while ((result != root) && (result.getParent().getLeft() != result))
            result = result.getParent();

        if (result != root) {
            // /不是一个满堆
            if (result.getParent().getRight() == null)
                result = result.getParent();
            else {
                result = (HeapNode<T>) result.getParent().getRight();
                // 不断的向下寻找最后的父结点
                while (result.getLeft() != null)
                    result = (HeapNode<T>) result.getLeft();
            }
        } else {// 当前堆是一个满堆
            while (result.getLeft() != null)
                result = (HeapNode<T>) result.getLeft();
        }

        return result;
    }

    @Override
    public T removeMin() throws EmptyCollectionException {
        if (isEmpty())
            throw new EmptyCollectionException("LinkedHeap");

        T minElement = root.getElement();

        if (size() == 1) {
            root = null;
            lastNode = null;
        } else {
            // 获取一个新的尾结点
            HeapNode<T> nextLast = getNewLastNode();

            if (lastNode.getParent().getLeft() == lastNode)
                lastNode.getParent().setLeft(null);
            else
                lastNode.getParent().setRight(null);

            ((HeapNode<T>) root).setElement(lastNode.getElement());

            lastNode = nextLast;
            heapifyRemove();
        }

        modCount++;

        return minElement;
    }

    /**
     * 这里面的规则其实比较简单 就是在描述的时候比较麻烦: 【1】首先我们需要在程序中找到当前的最后一个结点,
     * 【2】然后判断如果当前结点不是根节点,并且是父结点的左孩子,就不断的迭代向上查找;反之终止迭代
     * 【3】然后判断当前结点不是是根节点,就寻找当前结点父结点的左孩子 【4】获取当前结点的右孩子是不是空 如果不为空
     * 迭代一直到result的右孩子为空为止
     * 
     * @return
     * 
     *         返回最新的最末结点
     */
    private HeapNode<T> getNewLastNode() {
        HeapNode<T> result = lastNode;

        // 非根的右边结点
        while ((result != root) && (result.getParent().getLeft() == result))
            result = result.getParent();

        if (result != root)
            result = (HeapNode<T>) result.getParent().getLeft();

        while (result.getRight() != null)
            result = (HeapNode<T>) result.getRight();

        return result;
    }

    private void heapifyRemove() {

        T temp;
        HeapNode<T> node = (HeapNode<T>) root;//用户遍历的根结点
        HeapNode<T> left = (HeapNode<T>) node.getLeft();
        HeapNode<T> right = (HeapNode<T>) node.getRight();
        HeapNode<T> next;

        if ((left == null) && (right == null))
            next = null;
        else if (right == null)
            next = left;
        else if (((Comparable) left.getElement()).compareTo(right.getElement()) < 0)
            next = left;
        else
            next = right;

        temp = node.getElement();

        while ((next != null)
                && (((Comparable) next.getElement()).compareTo(temp) < 0)) {
            node.setElement(next.getElement());
            node = next;
            left = (HeapNode<T>) node.getLeft();
            right = (HeapNode<T>) node.getRight();

            if ((left == null) && (right == null))
                next = null;
            else if (right == null)
                next = left;
            else if (((Comparable) left.getElement()).compareTo(right
                    .getElement()) < 0)
                next = left;
            else
                next = right;
        }

        node.setElement(temp);

    }

    @Override
    public T findMin() {
        if (isEmpty())
            throw new EmptyCollectionException("LinkedHeap");

        return root.getElement();
    }

}
踏实 踏踏实实~
原文地址:https://www.cnblogs.com/mrzhang123/p/5365824.html