原理

基于数组完成二叉堆的构建,根据父结点n,俩个子节点为2n、2n+1这个基本规律可以构建一个完全二叉树,且所有父结点都满足大于子结点这个规则。通过上浮和下沉操作恢复堆的有序性,满足在logN时间复杂度下完成插入和删除操作。

API

优先队列API
init初始化容量大小,初始化结点数量
insert插入,在index标识后插入新节点,并完成上浮操作恢复堆有序性(父节点>子节点)
delete删除,记录索引为1的节点,把索引为index的结点赋值到索引为1的结点上,完成下沉操作恢复堆有序性,返回原头结点值

up

上浮

插入时调用,判断n/2与n索引值的大小(n为插入值的索引),如果父结点小于新插入的子结点则交换位置,直到满足条件为止
down下沉删除时调用,判断n(n为删除节点的索引=1)与子节点2n、2n+1的大小,如果不满足父结点>子结点的条件,则交换位置(调用swap方法),直到满足条件为止

swap

交换

交换两个索引的值(提取的公共方法)

dilatancy

扩容

本文未实现,插入时校验节点数量是否大于最大容量,对原数组进行2倍扩容

Shrink

缩容

本文未实现,删除时校验节点数量是否小于最大容量/4,对原数组进行2倍缩容

package leetcode.May;

/**
 * @description: 基于二叉堆的优先队列
 * @author: qiangyuecheng
 * @date: 2022/5/26 21:04
 */
public class PriorityQueue {

    private int[] source;
    private int index;

    public void init() {
        source = new int[10];
        index = 0;
    }

    /**
     * 插入
     */
    public void insert(int i) {
        //放到最后,上浮
        source[++index] = i;
        up();
    }

    /**
     * 删除头
     */
    public int delete() {
        //删除头,最后元素放到头,下沉
        int res = source[1];
        source[1] = source[index--];
        down();
        return res;
    }

    /**
     * 上浮
     */
    public void up() {
        int x = index;
        while (x > 1 && source[x] > source[x / 2]) {
            swap(x, x / 2);
            x /= 2;
        }
    }

    /**
     * 下沉
     */
    public void down() {
        int x = 1;
        while (2 * x <= index) {
            int maxIndex = source[x * 2] > source[x * 2 + 1] ? x * 2 : x * 2 + 1;
            if (source[x] < source[maxIndex]) {
                swap(x, maxIndex);
                x = maxIndex;
            } else {
                break;
            }
        }
    }

    public void swap(int i, int j) {
        int tmp = source[i];
        source[i] = source[j];
        source[j] = tmp;
    }


    public static void main(String[] args) {
        PriorityQueue priorityQueue = new PriorityQueue();
        priorityQueue.init();
        priorityQueue.insert(3);
        priorityQueue.insert(4);
        priorityQueue.insert(1);
        priorityQueue.insert(3);
        priorityQueue.insert(4);

        System.out.printf("" + priorityQueue.delete());
        System.out.printf("" + priorityQueue.delete());
        System.out.printf("" + priorityQueue.delete());


    }
}

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐