优先级队列:堆 大根堆小根堆 代码及其应用。

二叉树的顺序存储

使用数组保存二叉树,就是将二叉树用层序遍历的方式保存在数组当中,这种方式一般用来表示完全二叉树。

什么是堆?

1、堆是一颗完全二叉树
2、保存在数组当中
3、大根堆即任意结点的值都大于其子树中结点的值,又叫大堆或者最大堆
4、小根堆则跟大根堆相反,又叫小堆,最小堆。
5、堆一般用来快速查找集合中的最值。
关于堆的而代码实现:

/**
 * @ClassName TestHeap
 * @Description TODO
 * @Author 付小雷
 * @Date 2019/11/2522:21
 * @Version1.0
 **/
public class TestHeap {
    public int[] elem;
    public int usedSize;

    public TestHeap(){
        this.elem = new int[20];
        this.usedSize = 0;
    }
    public void adjustDown(int root ,int len){
        int parent = root;
        int child = 2*parent+1;
        while(child<len){
            if(child+1<len&&elem[child]<elem[child+1]){
                child = child+1;
            }
            if(elem[child]>elem[parent]){
                int tmp = elem[child];
                elem[child] = elem[parent];
                elem[parent] = tmp;
                parent = child;
                child = 2*parent+1;
            }else{
                break;
            }
        }
    }
    public void createHeap(int[] array) {
        for (int i = 0; i < array.length; i++) {
            this.elem[i] = array[i];
            this.usedSize++;
        }
        for (int i = (this.usedSize-1-1)/2; i >= 0; i--) {
            adjustDown(i,this.usedSize);
        }
    }
    public void adjustUp(int child) {
        int parent = (child-1)/2;
        while (child > 0) {
            if(this.elem[child] > this.elem[parent]) {
                int tmp = elem[child];
                elem[child] = elem[parent];
                elem[parent] = tmp;
                child = parent;
                parent = (child-1)/2;
            }else {
                break;
            }
        }
    }
    public boolean isFull(){
        return this.usedSize == this.elem.length;
    }
    public void pushHeap(int val) {
        if(isFull()) {
            this.elem = Arrays.copyOf
                    (this.elem,this.elem.length*2);
        }
        this.elem[this.usedSize] = val;
        this.usedSize++;//11
        adjustUp(usedSize-1);
    }

    public boolean isEmpty() {
        return this.usedSize == 0;
    }
    public void popHeap() {
        //0、堆为空 的时候
        if(isEmpty()) {
            return;
        }
        //1、根顶元素和最后一个元素进行交换
        int tmp = this.elem[0];
        this.elem[0] = this.elem[this.usedSize-1];
        this.elem[this.usedSize-1] = tmp;
        this.usedSize--;
        //2、向下调整,只需要调整0号下标这棵树
        adjustDown(0,this.usedSize);
    }
    public int getPop() {
        if(isEmpty()) {
            return -1;
        }
        return this.elem[0];
    }

    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(this.elem[i] +" ");
        }
        System.out.println();
    }
    public void heapSort(){
        int end = usedSize-1;
        //LinkedList list = new LinkedList<>();
        while(end>0){
            int tmp = this.elem[0];
            this.elem[0] = this.elem[end];
            this.elem[end] = tmp;
            //list.addFirst(this.elem[end]);
            adjustDown(0,end);
            end--;
        }
        //return list;
    }
}

TOP-K问题

用堆来解决TOP-K问题时,
需要找到前K个最大值时:
需要建立一个K长度的小根堆,然后遍历集合中所有的元素,将其和堆顶元素进行比较,如果大于堆顶元素则放入,然后进行向下调整,将其再次调整成为一个小根堆,在将集合遍历完成后,小根堆中的元素就是,前K个最大的元素。
反之要寻找前K个最小元素时,建立大根堆来解决。

你可能感兴趣的:(优先级队列:堆 大根堆小根堆 代码及其应用。)