zoukankan      html  css  js  c++  java
  • 数据结构(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();
        }
    
    }
    
    踏实 踏踏实实~
  • 相关阅读:
    javascript 备忘 细节 相关
    内存泄漏
    css相关 细节 优化 备忘
    nodeType
    事件冒泡 模型
    两个感叹号作用
    非冒泡事件
    DOM 对象
    Quartz2D 之 绘制文本
    Voilin 与 乐谱
  • 原文地址:https://www.cnblogs.com/mrzhang123/p/5365824.html
Copyright © 2011-2022 走看看