java——最大堆 MaxHeap

 使用数组来实现最大堆

堆是平衡二叉树

import Date_pacage.Array;

public class MaxHeap<E extends Comparable <E>> {
    private Array<E> data;
    public MaxHeap(int capacity) {
        data = new Array<>(capacity);
    }
    public MaxHeap() {
        data = new Array<>();
    }
    //heapify:讲任意数组整理成堆的形状 O(n)
    public MaxHeap(E[] arr) {
        data = new Array<>(arr);
        //从最后一个非叶子节点开始,逐个siftDown
        for(int i = parent(arr.length - 1) ; i >= 0 ; i-- ) {
            siftDown(i);
        }
    }
    public int size() {
        return data.getSize();
    }
    public boolean isEmpty() {
        return data.isEmpty();
    }
    //返回完全二叉树的数组(索引从0 开始)表示中,一个索引所表示的元素的父亲节点的索引
    private int parent(int index) {
        if(index == 0)
            throw new IllegalArgumentException("index-0 doesn't have parent.");
        return (index - 1) / 2;
    }
    
    private int leftChild(int index) {
        return index * 2 +1;
    }
    private int rightChild(int index) {
        return index * 2 + 2;
    }
    //向堆中添加元素
    public void add(E e) {
        data.addLast(e);
        siftUp(data.getSize() - 1);
    }
    private void siftUp(int k) {
        while(k > 0 && data.get(parent(k)).compareTo(data.get(k)) < 0){
            data.swap(k, parent(k));
            k = parent(k);
        }
    }
    //看堆中最大元素
    public E findMax() {
        if(data.getSize() == 0)
            throw new IllegalArgumentException("Can not findMax when heap is empty");
        return data.get(0);
    }
    //取出元素,只能取出最大的那个元素
    public E extractMax(){
        E ret = findMax();
        
        data.swap(0,  data.getSize() - 1);
        data.removeLast();
        siftDown(0);
        return ret;
    }
    private void siftDown(int k) {
        while(leftChild(k) < data.getSize()) {
            int j = leftChild(k);
            if(j + 1 < data.getSize() && 
                    data.get(j + 1).compareTo(data.get(j)) > 0) {
                j ++;
            }
            if(data.get(k).compareTo(data.get(j)) >= 0)
                break;
            data.swap(k,  j);
            k = j;
        }
    }
    // 取出堆中最大的元素,并且替换成元素e
    public E replace(E e) {
        E ret = findMax();
        data.set(0, e);
        siftDown(0);
        return ret;
    }

    
    
}

 

posted @ 2018-10-29 20:02  高圈圈  阅读(2993)  评论(0编辑  收藏  举报