美文网首页
最大堆的实现

最大堆的实现

作者: 小小飞的救赎 | 来源:发表于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