首页 > 其他分享 >PriorityQueue

PriorityQueue

时间:2024-07-13 23:18:52浏览次数:10  
标签:queue return int private PriorityQueue null size

  • PriorityQueue 是 Java 中的一个基于优先级堆的优先队列实现,它能够在 O(log n) 的时间复杂度内实现元素的插入和删除操作,并且能够自动维护队列中元素的优先级顺序。
// 传入比较器
PriorityQueue<String> priorityQueue = new PriorityQueue<>(Comparator.reverseOrder());

add()和 offer()

  • 前者在插入失败时抛出异常,后则则会返回false
public boolean add(E e) {
    return offer(e);
}
public boolean offer(E e) {
    // 不允许放入null元素
    if (e == null)
        throw new NullPointerException();
    modCount++;
    int i = size;
    if (i >= queue.length)
        // 扩容
        grow(i + 1);
    size = i + 1;
    if (i == 0)
        // 插入的是第一个元素
        queue[0] = e;
    else
        // 调整
        siftUp(i, e);
    return true;
}
// 向上调整
private void siftUp(int k, E x) {
    if (comparator != null)
        siftUpUsingComparator(k, x);
    else
        siftUpComparable(k, x);
}

private void siftUpUsingComparator(int k, E x) {
    while (k > 0) {
        int parent = (k - 1) >>> 1;
        Object e = queue[parent];
        if (comparator.compare(x, (E) e) >= 0)
            break;
        queue[k] = e;
        k = parent;
    }
    queue[k] = x;
}

private void siftUpComparable(int k, E x) {
    Comparable<? super E> key = (Comparable<? super E>) x;
    while (k > 0) {
        int parent = (k - 1) >>> 1;
        Object e = queue[parent];
        if (key.compareTo((E) e) >= 0)
            break;
        queue[k] = e;
        k = parent;
    }
    queue[k] = key;
}
  • 新加入的元素都是先插入到堆的末尾,也就是堆的最右下角,然后开始向上调整到合适的位置

element()和 peek()

  • 都是获取但不删除队首元素,前者当方法失败时前者抛出异常,后者返回null
public E peek() {
    return (size == 0) ? null : (E) queue[0];
}
// PriorityQueue调用的是父类AbstractQueue中的element()
public E element() {
    E x = peek();
    if (x != null)
        return x;
    else
        throw new NoSuchElementException();
}

remove()和 poll()

  • 获取并删除队首元素,区别是当方法失败时前者抛出异常,后者返回null
public E poll() {
    if (size == 0)
        return null;
    int s = --size;
    modCount++;
    E result = (E) queue[0];
    E x = (E) queue[s];
    queue[s] = null;
    if (s != 0)
        siftDown(0, x);
    return result;
}
private void siftDown(int k, E x) {
    if (comparator != null)
        siftDownUsingComparator(k, x);
    else
        siftDownComparable(k, x);
}

@SuppressWarnings("unchecked")
private void siftDownComparable(int k, E x) {
    Comparable<? super E> key = (Comparable<? super E>)x;
    int half = size >>> 1;        // loop while a non-leaf
    while (k < half) {
        int child = (k << 1) + 1; // assume left child is least
        Object c = queue[child];
        int right = child + 1;
        if (right < size &&
            ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
            c = queue[child = right];
        if (key.compareTo((E) c) <= 0)
            break;
        queue[k] = c;
        k = child;
    }
    queue[k] = key;
}

@SuppressWarnings("unchecked")
private void siftDownUsingComparator(int k, E x) {
    int half = size >>> 1;
    while (k < half) {
        // 左孩子下标
        int child = (k << 1) + 1;
        Object c = queue[child];
        // 右孩子下标
        int right = child + 1;
        if (right < size &&
            comparator.compare((E) c, (E) queue[right]) > 0)
            c = queue[child = right];
        if (comparator.compare(x, (E) c) <= 0)
            break;
        queue[k] = c;
        k = child;
    }
    queue[k] = x;
}
  • 删除堆顶元素,用堆中最后一个元素顶替堆顶,然后把新的堆顶与左右孩子比较,向下调整

remove(Object o)

public boolean remove(Object o) {
    int i = indexOf(o);
    if (i == -1)
        return false;
    else {
        removeAt(i);
        return true;
    }
}

private int indexOf(Object o) {
    if (o != null) {
        for (int i = 0; i < size; i++)
            if (o.equals(queue[i]))
                return i;
    }
    return -1;
}

private E removeAt(int i) {
    // assert i >= 0 && i < size;
    modCount++;
    int s = --size;
    if (s == i) // removed last element
        queue[i] = null;
    else {
        E moved = (E) queue[s];
        queue[s] = null;
        siftDown(i, moved);
        if (queue[i] == moved) {
            siftUp(i, moved);
            if (queue[i] != moved)
                return moved;
        }
    }
    return null;
}

标签:queue,return,int,private,PriorityQueue,null,size
From: https://www.cnblogs.com/sprinining/p/18300967

相关文章

  • PriorityQueue(优先队列)
    hot100的常用JAVAAPI:PriorityQueue(优先队列)文章目录hot100的常用JAVAAPI:PriorityQueue(优先队列)一、PriorityQueue是什么?二、常用函数1.初始化2.修改变成大顶堆(默认是小顶堆)2.队列中插入元素3.获取元素(最小值或者最大值)4.判断是否包含某个元素、移除指定元素、......
  • 我什么时候应该使用TreeMap 而不是 PriorityQueue?反之亦然?
    引子之前周赛(第390场周赛记录-快手)时遇到一题(题干描述见下图,实现代码见周赛记录),需要保持容器元素的动态有序(即随着插入删除操作后列表始终是有序的)。尝试过很多数据结构或方案,如列表存储然后手动调用Arrays.sort()进行排序、使用优先队列实现大/小根堆的方式,但无一例外全部超时......
  • PriorityQueue源码阅读
    目录简介模型代码分析成员变量方法总结参考链接本人的源码阅读主要聚焦于类的使用场景,一般只在java层面进行分析,没有深入到一些native方法的实现。并且由于知识储备不完整,很可能出现疏漏甚至是谬误,欢迎指出共同学习本文基于corretto-17.0.9源码,参考本文时请打开相应的源码对照,......
  • 【leetcode 239. 滑动窗口最大值】Java优先队列——PriorityQueue类
    leetcode239.滑动窗口最大值题目描述:1e5大小的nums[]数组中长度为k(1<=k<=1e5)的窗口的最大值题解:暴力求解O(n^2)会超时,需要O(nlogn)的解法使用大根堆优先队列维护窗口元素,每次取最大值复杂度降为O(1),堆结构维护复杂度O(logn)问:如果维护窗口[l,r]前[0,l-1]的元素不影......
  • Collection - PriorityQueue源码解析
    前面以JavaArrayDeque为例讲解了Stack和Queue,其实还有一种特殊的队列叫做PriorityQueue,即优先队列。优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素,C++的优先队列每次取最大元素)。这里牵涉到了大小关系,元素大小的评判可以通过元素本身......
  • 优先级队列PriorityQueue在算法问题中的使用
    文章目录优先级队列介绍与优先级队列有关的习题[179.最大数][918.环形子数组的最大和][1094.拼车][264.丑数II]前k个出现频率最高的数字用优先级队列合并k个有序链表滑动窗口的最大值其他:对二维数组自定义排序优先级队列介绍优先队列一般基于二叉堆实现,二叉堆:堆的根节点的优......
  • 开源优先队列FastPriorityQueue源码阅读
    FastPriorityQueue  源码连接:https://github.com/BlueRaja/High-Speed-Priority-Queue-for-C-Sharp  大致结构:  1节点在内存中的结构还是数组,且首节点为无意义节点,有效节点从索引1开始。(见FastPriorityQueue的T[]_nodes)  2维护的节点必须时固定的继承。(见FastPri......
  • 优先队列(PriorityQueue)常用方法及简单案例
    1前言PriorityQueue是一种特殊的队列,满足队列的“队尾进、队头出”条件,但是每次插入或删除元素后,都对队列进行调整,使得队列始终构成最小堆(或最大堆)。具体调整如下:插入......
  • 数据结构 玩转数据结构 8-8 Java中的PriorityQueue
    0课程地址https://coding.imooc.com/lesson/207.html#mid=13745 1重点关注1.1用java自带的优先队列实现取前k个高频元素问题见3.1 1.2......
  • Java容器之PriorityQueue源码分析
    一、简介优先级队列,是0个或多个元素的集合,集合中的每个元素都有一个权重值,每次出队都弹出优先级最大或最小的元素。一般来说,优先级队列使用堆来实现。二、源码分析2.1......