1. 程式人生 > >PriorityQueue底層堆的實現與應用

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