美文网首页
最大堆的实现

最大堆的实现

作者: 小小飞的救赎 | 来源:发表于2018-10-17 11:37 被阅读0次
    /**
     * 数据结构:最大堆(基于【我自定义的】链表)
     * 描述:实现了 添加、删除、判空、判断、上浮、下沉、是否存在
     * @author hcc
     *
     */
    public class ArrayHeap<E extends Comparable<E>> {
        private HLinkList<E> array;
        
        public ArrayHeap() {
            array = new HLinkList<E>();
        }
        
        /**
         * 向堆中添加元素【先添加元素,在上浮到指定位置】
         * @param e
         */
        public void add(E e) {
            array.add(e);
            goUp();
        }
        
        /**
         * 上浮操作
         */
        private void goUp() {
            int index = array.getSize() - 1;
            int parentIndex = getParentIndex(index);
            while (true) {
                if (array.get(index).compareTo(array.get(parentIndex)) > 0) {
                    swap(index, parentIndex);
                    index = parentIndex;
                    parentIndex = getParentIndex(parentIndex);
                } else {
                    break;
                }
            }
        }
        
        /**
         * 数据交换操作
         * @param index 子节点的索引值
         * @param parentIndex 父节点的索引值
         */
        private void swap(int index,int parentIndex) {
            int size = array.getSize();
            if(index > (size-1) || parentIndex >  (size-1)) {
                throw new IllegalArgumentException("索引值错误!");
            }
            E temporary = array.get(index);
            array.set(index, array.get(parentIndex));
            array.set(parentIndex, temporary);
            
        }
        
        /**
         * 通过index节点的索引获取父节点的索引
         * @param index 
         * @return 父节点的索引
         */
        private int getParentIndex(int index) {
            if(index < 0) {
                throw new IllegalArgumentException("索引的值小于0!");
            }
            return (index-1)/2;
        }
        
        /**
         * 通过index节点的索引获取左子节点的索引
         * @param index
         * @return
         */
        private int getLeftIndex(int index) {
            if(index < 0) {
                throw new IllegalArgumentException("索引的值小于0!");
            }
            return (2*index+1);
        }
        
        /**
         * 通过index节点的索引获取有子节点的索引
         * @param index
         * @return
         */
        private int getRightIndex(int index) {
            if(index < 0) {
                throw new IllegalArgumentException("索引的值小于0!");
            }
            return (2*index+2);
        }
        
        /**
         * 
         * @return 返回堆中最大的数据
         */
        public E findMax() {
            if(array.getSize() == 0) {
                throw new IllegalArgumentException("堆中无数据!!!");
            }
            return array.get(0);
        }
        /**
         * 从堆中取出最大数【取出后堆的排列顺序发生变化,需要在删除后的堆中再找到最大数】
         */
        public E getMax() {
            E e = findMax();
            swap(0,array.getSize()-1);
            array.remove(array.getSize()-1);
            moveDown(0);
            return e;
        }
        
        /**
         * 下移操作
         * @param index
         */
        private void moveDown(int index) {
            if(index < 0) {
                 throw new IllegalArgumentException("索引的值小于0!");
            }
            while(getLeftIndex(index) < array.getSize()) {
                int i = 0;
                E e = array.get(index);
                int childLeft = getLeftIndex(index);
                int childRight = getRightIndex(index);
                
                E childLeftData = array.get(childLeft);
                
                i = childLeft;
                if(childRight < array.getSize() && array.get(childRight).compareTo(childLeftData) >= 0) {
                    i = childRight;
                }
                if(e.compareTo(array.get(i)) >= 0) {
                    break;
                }
                swap(index,i);
                index = i;
            }   
        }
        /**
         * 
         * @return 数据数量
         */
        public int getSize() {
            return array.getSize();
        }
        /**
         * 
         * @param e
         * @return true表示堆中存在 false表示堆中不存在
         */
        public boolean contain(E e) {
            return array.contains(e);
        }
        /**
         * 
         * @return true表示为空 false表示不为空
         */
        public boolean isEmpty() {
            return array.isEmpty();
        }
        
        
        public String toString() {
            return array.toString();
        }
    }

    相关文章

      网友评论

          本文标题:最大堆的实现

          本文链接:https://www.haomeiwen.com/subject/kuilzftx.html