大把博客在公司电脑和ipad上,等时机到了上传,这段时间就这么写着吧
开门见山,为啥要用这个队列。
优先队列:自动从小到大排序,为什么???源码安排的明明白白,上马。。。
offer()方法:增加元素
/**
* Inserts the specified element into this priority queue.
*
* @return {@code true} (as specified by {@link Queue#offer})
* @throws ClassCastException if the specified element cannot be
* compared with elements currently in this priority queue
* according to the priority queue's ordering
* @throws NullPointerException if the specified element is null
*/
public boolean offer(E e) {
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;
}
siftUp()比较并排序
/**
* Inserts item x at position k, maintaining heap invariant by
* promoting x up the tree until it is greater than or equal to
* its parent, or is the root.
*
* To simplify and speed up coercions and comparisons. the
* Comparable and Comparator versions are separated into different
* methods that are otherwise identical. (Similarly for siftDown.)
*
* @param k the position to fill
* @param x the item to insert
*/
private void siftUp(int k, E x) {
if (comparator != null)
siftUpUsingComparator(k, x);
else
siftUpComparable(k, x);
}
接下来的我不用多说了吧,嘻嘻。
java5引入的这个东东,实现了Queue接口,追踪源码确实是起源自java1.5,然后属于java Collections Framework的成员
/**
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @since 1.5
* @author Josh Bloch, Doug Lea
* @param <E> the type of elements held in this collection
*/
优先级队列的特点:还是追踪源码,从源码中一点点解释
One:使用时的注意事项
/**
* An unbounded priority {@linkplain Queue queue} based on a priority heap.
* The elements of the priority queue are ordered according to their
* {@linkplain Comparable natural ordering}, or by a {@link Comparator}
* provided at queue construction time, depending on which constructor is
* used. A priority queue does not permit {@code null} elements.
* A priority queue relying on natural ordering also does not permit
* insertion of non-comparable objects (doing so may result in
* {@code ClassCastException}).
*/
翻译结果
基于优先级堆的无界优先级{@linkplain Queue Queue}。
优先队列的元素按照它们的顺序排列
{@linkplain Comparable natural order},或者使用{@link Comparator}
在队列构建时提供,具体取决于使用哪个构造函数。
优先队列不允许{@code null}元素。
依赖于自然顺序的优先队列也不允许插入不可比较的对象(这样做可能会导致 {@code ClassCastException})。
Two:对头结点的操作
* <p>The <em>head</em> of this queue is the <em>least</em> element
* with respect to the specified ordering. If multiple elements are
* tied for least value, the head is one of those elements -- ties are
* broken arbitrarily. The queue retrieval operations {@code poll},
* {@code remove}, {@code peek}, and {@code element} access the
* element at the head of the queue.
翻译结果:
该队列的<em>head</em>是相对于指定顺序的<em>least</em>元素。如果多个元素以最小值绑定,则head就是这些元素之一——绑定是任意断开的。队列检索操作{@code poll},
{@code remove}、{@code peek}和{@code element}访问队列头部的元素。
Three:界限
* <p>A priority queue is unbounded, but has an internal
* <i>capacity</i> governing the size of an array used to store the
* elements on the queue. It is always at least as large as the queue
* size. As elements are added to a priority queue, its capacity
* grows automatically. The details of the growth policy are not
* specified.
大致意思:
优先队列是无界的,但是有一个内部容量用来控制队列中用来存储元素数组的大小。
它的值总是总是至少和队列大小一样。(看到了哈,这个队列的内部数据结构是数组)
当元素被添加到队列的时候,队列的容量会随着自动增长。(等会通过源码来看为什么)
没有确定的增长策略(有点坑哈?好奇内部的实现)
Four:关于优先级队列迭代器
* <p>This class and its iterator implement all of the
* <em>optional</em> methods of the {@link Collection} and {@link
* Iterator} interfaces. The Iterator provided in method {@link
* #iterator()} is <em>not</em> guaranteed to traverse the elements of
* the priority queue in any particular order. If you need ordered
* traversal, consider using {@code Arrays.sort(pq.toArray())}.
六级分很低的翻译,凑合,凑合
这个优先级类和迭代器实现了Collection和Iterator接口中所有可以实现的方法。其中
迭代器方法并没有提供以任何特定顺序遍历优先级队列,如果要进行有序遍历则需要使用
Arrays.sort(PQ.toArray)方法
Five:同步问题
<p><strong>Note that this implementation is not synchronized.</strong>
* Multiple threads should not access a {@code PriorityQueue}
* instance concurrently if any of the threads modifies the queue.
* Instead, use the thread-safe {@link
* java.util.concurrent.PriorityBlockingQueue} class.
(很明显优先级队列不是同步的,多个线程访问会引发线程安全问题)
不翻译了。。。。。
就是说不安全,如果想要使用安全的队列,就使用线程安全的阻塞优先队列,在多线程中,这种队列可以用开构造线程池的阻塞队列
Six:你最关心的复杂度问题
*<p>Implementation note: this implementation provides
* O(log(n)) time for the enqueuing and dequeuing methods
* ({@code offer}, {@code poll}, {@code remove()} and {@code add});
* linear time for the {@code remove(Object)} and {@code contains(Object)}
* methods; and constant time for the retrieval methods
* ({@code peek}, {@code element}, and {@code size}).
菜鸟翻译:
这个实现类提供了出队列,进队列时间复杂度为O(log(n))的poll,offer,remove,add(关于其中的方法的运用,后面有机会提),
线性时间方法:offer(),contains()
常数时间方法:peek(),element(),size()
真的发现了新大陆,自己忽略了这么好用的东东
LeetCode 23 题解
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法:要我自己解肯定要用先合并两个,然后再依次合并两个,直到合并完,麻烦
上牛逼网友代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists == null || lists.length < 0){
return null;
}
//创建优先级队列
PriorityQueue<Integer> queue = new PriorityQueue();
//遍历并存储node
for(ListNode node:lists){
while(node != null){
queue.add(node.val);
node = node.next;
}
}
ListNode res = new ListNode(0);
ListNode tmp= res;
while(!queue.isEmpty()){
ListNode temp = new ListNode(queue.poll());
tmp.next = temp;
tmp = tmp.next;
}
return res.next;
}
}