二叉堆和优先队列

141 阅读1分钟

二叉堆特点

  • 完全二叉树
  • 父亲节点大于子节点。、
  • 只取出最大的元素,(堆顶)

二叉堆的基础代码,(根据完成二叉树的特点,基于数组的一种实现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<>();
    }
    public int size(){
        return data.getSize();
    }

    public boolean isEmpty(){
        return data.isEmpty();
    }

    private int parent(int index){
        if (index == 0)
            throw new IllegalArgumentException("index 0 ");
        return (index-1)/2;
    }

    private int leftChild(int index){
        return index*2+1;
    }
    private int rightChild(int index){
        return index*2+2;
    }
}

向堆中添加元素,SiftUP

  • 在数组的最后添加一个元素
  • 和父亲节点比较,siftup

从堆中删除元素

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++;

            // data[j] 是左右孩子中的最大值
            //data[j] he data[k] compare
            if (data.get(k).compareTo(data.get(j))>=0)
                break;
            data.swap(k,j);
            k=j;


        }
    }
    
    
    

替换元素

    public E replace(E e){
        E ret=findMax();
        data.set(0,e);
        siftDown(0);
        return ret;
    } 

heapify 复杂度 log(N)

public MaxHeap(E[] arr){
    data=new Array<E>(arr);
    for (int i=parent(data.getSize()-1);i>=0;i--){
        siftDown(i);
    }

}

PriorityQueue

优先队列可以基于上面我们自己实现的最大堆实现


public class PriorityQueue<E extends Comparable<E>>  implements Queue<E>{

    private MaxHeap<E> maxHeap;

    public PriorityQueue() {
        maxHeap=new MaxHeap<>();
    }

    @Override
    public int getSize() {
        return maxHeap.size();
    }

    @Override
    public boolean isEmpty() {
        return maxHeap.isEmpty();
    }

    @Override
    public void enqueue(E e) {
        maxHeap.add(e);

    }

    @Override
    public E dequeue() {
        return maxHeap.extractMax();
    }

    @Override
    public E getFront() {
        return maxHeap.findMax();
    }
}

java.utils.PriorityQueue

是最小堆,而且增加了许多新的特性。比如可以在构造方法传入Comparator比较器。