PriorityQueue底层堆的实现与应用

堆的实现
在Collection接口下,我们学习的最后一个数据结构就是Queue。后面我们将会剖析一下PriorityQueue(优先级队列)的源码。PriorityQueue的底层是基于堆实现的,那么首先我们先了解一下什么是堆。
之前有学习过二叉树或者堆排序,堆的数据结构就与这个类似。

在这里插入图片描述
堆分为大根堆和小根堆,如图我们演示了一个小根堆的生成。小根堆只要保证你的堆顶是最小的元素(大根堆同理)。那么我们现在自定义实现一个堆,完成大根堆和小根堆的调整。

import java.util.Arrays;

/**
 * 描述:Heap
 *
 * @Author administrator{GINO ZHANG}
 * @Date2018/11/10
 */
public class HeapTest {
    private int[] array;
    private int Usedsize;
    private int top;


    public HeapTest() {
        this(5);
    }

    public HeapTest(int Usedsize){
        this.array = new int[Usedsize];
        this.top  = 0;
    }

    /**
     * 添加元素的方法
     * @param value 添加的元素
     */
    public void add(int value){
        if (isFull()){
            this.array = Arrays.copyOf(this.array, 2*this.array.length);
        }
        if (this.Usedsize == 0){
            this.array[0] = value;
            Usedsize++;
        }else{
            this.array[Usedsize] = value;
            shftUp(Usedsize,value);
        }
    }

    private boolean isFull() {
        return this.Usedsize == this.array.length;
    }

    @Override
    public String toString() {
        return "HeapTest{" +
                "array=" + Arrays.toString(array) +
                '}';
    }

    /**
     * 调整为小根堆
     * @param index 插入元素的下标
     * @param value 插入的元素
     */
    private void shftUp(int index, int value) {
        while (index > 0){
            int parent = (index - 1)/2;
            if (array[parent] <= value){
                break;
            }
            array[index] = array[parent];
            index = parent;
        }
        array[index] = value;
        Usedsize++;
    }

    /**
     * 删除堆顶元素
     * @param
     * @return
     */
    public void  remove() {
        array[0] = array[Usedsize - 1];
        array[Usedsize-1]= array[Usedsize];
        for (int i = (Usedsize - 1) / 2; i >= 0; i--) {
            shftDown(i, Usedsize-1);
        }
        Usedsize--;
    }

    private void shftDown(int start,int end){
        int tmp = array[start];
        for(int i = 2*start+1; i <= end;i = i*2+1) {
            if((i < end-1) && array[i] < array[i+1]) {
                i++;
            }
            if(array[i] > tmp) {
                array[start] = array[i];
                start = i;
            }
            if(array[i] <= tmp) {
                break;
            }
        }
        array[start] = tmp;
    }


    /**
     * 获取堆顶元素
     * @return
     */
    public int peek(){
        return this.array[top];
    }

    public static void main(String[] args) {
        HeapTest heapTest = new HeapTest();
        System.out.println(heapTest);
        for (int i = 0;i<9;++i){
            heapTest.add(i);
        }
        System.out.println(heapTest);

        System.out.println(heapTest.peek());

        heapTest.remove();
        System.out.println(heapTest);
        System.out.println(heapTest.peek());
    }
}

输出结果:

C:\java\java7\jdk1.7.0_80\bin\java.exe -javaagent:D:\ideaIU-2018.1.5.win\lib\idea_rt.jar=39403:D:\ideaIU-2018.1.5.win\bin 
HeapTest{array=[0, 0, 0, 0, 0]}
HeapTest{array=[0, 1, 2, 3, 4, 5, 6, 7, 8, 0]}
0
HeapTest{array=[8, 7, 6, 3, 4, 5, 2, 1, 0, 0]}
8

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/weixin_42262357/article/details/84038539