堆(PriorityQueue)

实现一波堆

package heap;

import java.util.Arrays;
import java.util.Comparator;

/**
 *  扩容的事情就交给读者了!!
 *
 */
public class HeapQueue<E extends Comparable> {
    private E[] arr;
    private int size = 0;
    private int capacity = 10;
    Comparator<E> comparable; // 比较器!


    public HeapQueue(int capacity) {
        this.capacity = capacity;
        arr = (E[]) new Object[capacity];
        size = 0;
    }

    public HeapQueue(int capacity, Comparator<E> comparable) {
        this.capacity = capacity;
        this.comparable = comparable;
        arr = (E[]) new Object[capacity];
        size = 0;
    }

    // 把数组直接建立成为一个堆
    public HeapQueue(E[] arr) {
        this.arr = arr;
        this.size = arr.length;
        this.capacity = arr.length;
        buildHeap(arr);
    }
    // 把数组直接建立成为一个堆
    public HeapQueue(E[] arr,Comparator<E> comparable) {
        this.arr = arr;
        this.size = arr.length;
        this.capacity = arr.length;
        this.comparable = comparable;
        buildHeap(arr);
    }


    private void buildHeap(E[] arr){
        // 将一个数组建立成一个堆!
        int child = (size - 2)/2; // 从下到上从右到左第一个非叶子节点开始依次向下调整!
        while(child >= 0){
            shiftDown(arr,child);
            child--;
        }
    }

    public void offer(E val){
        // 这里要有 扩容机制
        arr[size++] = val;
        shiftDown(arr,size - 1); // 向上调整!
    }

    public E poll() throws Exception {
        if(size < 1) throw new Exception("error : size = "+ size);
        E old = arr[0];
        arr[0] = arr[size - 1];
        size --;
        adjustDown(arr,0);
        return  old;
    }

    public E peek() throws Exception {
        if(size < 1) throw new Exception("error : size = "+ size);
        return arr[0];
    }
    // 向下调整!
    private void shiftDown(E[] heap,int index){
        if(comparable == null)  shiftDownWithNo(heap,index);
        else shiftDownWithOne(heap,index);
    }

    // 向上调整
    private void adjustDown(E[] heap,int index){
        if(comparable == null) adjustDownNo(heap,index);
        else adjustDownWithOne(heap,index);
    }

    private void adjustDownNo(E[] heap,int index){
        int cur = index;
        int parent = index;
        while(parent >= 0){
            parent = cur >> 1;
            if(arr[cur].compareTo(parent) >= 0){
                break;
            }
            swap(arr,cur,parent);
            cur = parent;
        }
    }

    private void adjustDownWithOne(E[] heap,int index){
        int cur = index;
        int parent = index;
        while(parent >= 0){
            parent = cur >> 1;
            if(comparable.compare(arr[cur],arr[parent]) >= 0){
                break;
            }
            swap(arr,cur,parent);
            cur = parent;
        }
    }


    // 未曾传入比较器
    private void shiftDownWithNo(E[] heap,int index){
            int cur = index;
            int leftChild = index * 2 + 1; // 左孩子位置!
            while(leftChild < size){
                if(leftChild+ 1 < size && heap[leftChild].compareTo(heap[leftChild+1]) > 0){
                    leftChild++;
                }
                if(heap[cur].compareTo(heap[leftChild]) <= 0){
                    break;
                }
                swap(heap,cur,leftChild);
                cur = leftChild;
                leftChild = leftChild * 2 + 1;
            }

    }
    // 传入比较器!
    private void shiftDownWithOne(E[] heap,int index){
        int cur = index;
        int leftChild = index * 2 + 1; // 左孩子位置!
        while(leftChild < size){
            if(leftChild+ 1 < size &&  comparable.compare(heap[leftChild],heap[leftChild+1]) > 0){
                leftChild++;
            }
            if(comparable.compare(heap[cur],heap[leftChild]) <= 0){
                break;
            }
            swap(heap,cur,leftChild);
            cur = leftChild;
            leftChild = leftChild * 2 + 1;
        }

    }

    private void swap(E[] arr,int i,int j){
        // 交换层面
        E e = arr[i];
        arr[i] = arr[j];
        arr[j] = e;
    }


    public int size(){
        return size;
    }

    public static void main(String[] args) {
        Integer[] arr =  { 1,5,3,8,7,6 };
        HeapQueue<Integer> heap = new HeapQueue<>(arr,((o1, o2) -> o2 - o1));
         //  heap.shiftDown(heap.arr,0);

        System.out.println(Arrays.toString(arr));
    }
}

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值