java 优先队列用法

合集下载

自己动手实现java数据结构(八)优先级队列

自己动手实现java数据结构(八)优先级队列

⾃⼰动⼿实现java数据结构(⼋)优先级队列1.优先级队列介绍1.1 优先级队列 有时在调度任务时,我们会想要先处理优先级更⾼的任务。

例如,对于同⼀个柜台,在决定队列中下⼀个服务的⽤户时,总是倾向于优先服务VIP⽤户,⽽让普通⽤户等待,即使普通的⽤户是先加⼊队列的。

优先级队列和普通的先进先出FIFO的队列类似,最⼤的不同在于,优先级队列中优先级最⾼的元素总是最先出队的,⽽不是遵循先进先出的顺序。

1.2 堆 优先级队列的接⼝要求很简单。

从逻辑上来说,、或者等数据结构都可⽤于实现优先级队列。

但考虑到时间和空间的效率,就必须仔细斟酌和考量了。

⽽⼀种被称为堆的数据结构⾮常适合实现优先级队列。

’ 堆和⼆叉搜索树类似,存储的元素在逻辑上是按照层次排放的,在全局任意地⽅其上层元素优先级⼤于下层元素,这⼀顺序性也被称为堆序性,⽽其中优先级最⼤的元素被放在最⾼的层级(⼤顶堆)。

和⼆叉搜索树的排序⽅式不同的是,堆中元素的顺序并不是完全的排序,⽽只是维护了⼀种偏序关系,被称为堆序性。

在这种偏序关系下,元素之间的顺序性⽐较疏散,维护堆序性的代价⽐较低,因⽽在实现优先级队列时,堆的效率要⾼于平衡⼆叉搜索树。

1.3 完全⼆叉堆 完全⼆叉堆是堆的⼀种,其元素在逻辑上是以完全⼆叉树的形式存放的,但实际却是存储在向量(数组)中的。

在这⾥,我们使⽤完全⼆叉堆来实现优先级队列。

2.优先级队列ADT接⼝/*** 优先级队列 ADT接⼝*/public interface PriorityQueue <E>{/*** 插⼊新数据* @param newData 新数据* */void insert(E newData);* @return当前优先级最⼤的数据* */E peekMax();/*** 获得并且删除当前优先级最⼤值* @return被删除的当前优先级最⼤的数据*/E popMax();/*** 获得当前优先级队列元素个数* @return当前优先级队列元素个数* */int size();/*** 是否为空* @return true 队列为空* false 队列不为空* */boolean isEmpty();}3.完全⼆叉堆实现细节3.1 基础属性 完全⼆叉堆内部使⽤之前封装好的向量作为基础。

[Java]-优先队列,二叉堆,堆排序

[Java]-优先队列,二叉堆,堆排序

[Java]-优先队列,⼆叉堆,堆排序泛型优先队列API返回值⽅法名作⽤构造函数MaxPQ()创建⼀个优先队列构造函数MaxPQ(int N)创建⼀个⼤⼩为N的优先队列构造函数MaxPQ(Key[] a)利⽤数组a创建⼀个优先队列void insert(Key v)向队列中插⼊元素vKey Max()返回最⼤元素Key delMax()删除最⼤元素并返回boolean isEmpty()判断优先队列是否为空int size()返回优先队列的⼤⼩优先队列最重要的操作就是删除最⼤元素和插⼊元素⼀个优先队列的⽤例package cn.ywrby.test;import edu.princeton.cs.algs4.*;//⼀个优先队列的⽤例//输⼊多组数据,打印出其中最⼤的M⾏数据//tinyBatch.txt测试⽤例public class TopM {public static void main(String[] args){int M=5;MinPQ<Transaction> pq=new MinPQ<Transaction>(M+1);while(StdIn.hasNextLine()){pq.insert(new Transaction(StdIn.readLine())); //将输⼊插⼊优先队列if(pq.size()>M){ //当队列长度⼤于输出长度,删除最⼩值pq.delMin();}}//将队列中的元素放⼊栈,然后输出,实现倒序Stack<Transaction> stack=new Stack<Transaction>();while(!pq.isEmpty()){stack.push(pq.delMin());}for(Transaction t:stack){StdOut.println(t);}}}⼆叉堆在⼆叉堆的数组中,每个元素都保证⼤于等于另外两个特定位置的元素,以此类推,便得到这种结构当⼀棵⼆叉树的每个节点都⼤于等于它的两个⼦节点时,它被称为堆有序易知,根节点是对有序的⼆叉树的最⼤节点⼆叉堆是⼀组能够⽤对有序的完全⼆叉树排序的元素,并在数组中按照层级储存(不使⽤数组的第⼀个位置)在⼀个堆中,位置k的结点的⽗结点的位置为(k2)向下取整(2k)向下取整,⽽它的⼦节点的位置分别为2k,2k+1。

Java中数组自定义排序与优先级队列笔记

Java中数组自定义排序与优先级队列笔记

Java中数组⾃定义排序与优先级队列笔记今天在⼒扣每⽇⼀题中⼜遇到了需要取出数组前n个元素的,第⼀时间想到使⽤Arrays的sort排序,应该可以⾃定义⽐较器,或者使⽤⼤顶堆(优先级队列),但是⼀下没有写出来,还是去查了下资料,因此在这做个笔记以备⽆患。

Arrays的sort⾃定义⽐较器:Arrays.sort(数组,(a,b)->{return a-b(升序)/b-a(降序)});或者使⽤匿名类Arrays.sort(数组,new Comparator<>() { public int compare(int[] a,int[]b){return a-b(升序)/b-a(降序)});最后使⽤Arrays.copyOfRange(原数组, 起点, 终点)返回原数组的⼦数组即可。

时间复杂度是nlogn,n为数组元素个数由于⾃定义⽐较器实现快排需要对数组⾥所有元素都进⾏排序,在这种题⽬中只需要取满⾜条件的前k个即可,因此可以使⽤固定k容量的⼤顶堆结构进⾏求解,采⽤的是PriorityQueue的api接⼝。

⾸先定义⼀个优先级队列,定义其⽐较策略,这⾥采⽤的是逆序,因此堆顶元素为最不符合要求的,每次只要和堆顶元素对⽐即可。

PriorityQueue<int[]> pq = new PriorityQueue<int[]>(new Comparator<int[]>() {public int compare(int[] array1, int[] array2) {return array2[0] - array1[0];}});然后将数组前k项加⼊队列,完成初始化for (int i = 0; i < K; ++i)pq.offer(new int[]{points[i][0] * points[i][0] + points[i][1] * points[i][1], i});最后后续项依次和堆顶进⾏⽐较,如果满⾜则抛出堆顶,将该项加⼊,PriorityQueue会按照⽐较策略重新⽣成堆顶。

priorityqueue方法

priorityqueue方法

priorityqueue方法PriorityQueue方法PriorityQueue是Java中的一个常用数据结构,它的作用是维护一个优先级队列,即每次从队列中取出元素时,会先取出优先级最高的元素。

本文将介绍PriorityQueue的使用方法,以及一些常用操作。

1. 声明PriorityQueue在使用PriorityQueue之前,需要先声明一个PriorityQueue。

一个简单的声明方法如下:```PriorityQueue<Integer> pq = new PriorityQueue<Integer>();```这个声明表示,我们创建了一个优先级队列pq,其中的元素是整数。

2. 添加元素添加元素到PriorityQueue的方法是add()。

例如,如果要向一个优先级队列pq中添加值为5的元素,可以使用以下代码:pq.add(5);```3. 取出元素从PriorityQueue中取出元素的方法是poll()。

此方法取出优先级最高的元素,并从队列中删除它。

例如,如果我们要从一个优先级队列pq中取出优先级最高的元素,可以使用以下代码:```int highestPriority = pq.poll();```这个代码表示取出了当前队列中优先级最高的元素,并将其保存在highestPriority变量中。

4. 访问元素我们可以使用peek()方法来查看当前队列中优先级最高的元素,但是它并不会从队列中删除这个元素。

例如,如果我们要查看一个优先级队列pq中优先级最高的元素,可以使用以下代码:```int highestPriority = pq.peek();5. 修改元素PriorityQueue中的元素是按照优先级排序的,因此不能直接修改某个元素的值。

如果需要修改元素,需要先将该元素从队列中删除,然后再将修改后的元素添加回队列中。

6. 遍历元素我们可以使用迭代器来遍历PriorityQueue中的所有元素。

javaqueue的用法

javaqueue的用法

javaqueue的用法Java Queue 的用法Java Queue 是一种基于 FIFO(先进先出)原则的集合框架,可以用于存储和管理一组元素。

在Java 中,Queue 接口是一个标准的接口,它定义了队列的基本操作方法。

Queue 接口有许多实现类,包括LinkedList、PriorityQueue 和 ArrayDeque 等。

1. 创建一个 Queue在 Java 中创建一个 Queue 可以使用以下代码:```Queue<String> queue = new LinkedList<>();```这将创建一个 LinkedList 类型的队列。

您也可以使用 PriorityQueue 或 ArrayDeque 类型来创建队列。

2. 添加元素到队列Java Queue 提供了两种方法来添加元素到队列中:```offer(E element):将指定元素插入此队列。

add(E element):将指定元素插入此队列。

如果插入失败,则抛出异常。

```示例代码:```queue.offer("a");queue.add("b");queue.offer("c");```3. 获取并删除队首元素Java Queue 提供了两种方法来获取并删除队首元素:```poll():获取并删除此队列的头部。

remove():获取并删除此队列的头部。

如果操作失败,则抛出异常。

```示例代码:```String head = queue.poll();System.out.println(head);String head2 = queue.remove();System.out.println(head2);```输出结果为:```ab```4. 获取但不删除队首元素Java Queue 提供了两种方法来获取但不删除队首元素:```peek():获取但不删除此队列的头部。

java队列方法

java队列方法

java队列方法队列是一种常见的数据结构,用于存储和管理一系列元素。

它遵循先进先出(First-In-First-Out,FIFO)的原则,即最先添加到队列的元素最先被移除。

在Java中,队列是通过Queue接口和其实现类实现的。

Queue接口定义了队列的基本操作,如添加元素、移除元素和获取队列头部元素等。

它是Java集合框架的一部分,位于java.util包中。

以下是Queue接口中常用的方法:1. add(E e):将元素e添加到队列的尾部,如果添加成功,则返回true;如果添加失败(例如队列已满),则抛出异常。

2. offer(E e):将元素e添加到队列的尾部,如果添加成功,则返回true;如果添加失败,则返回false。

3. remove(:移除并返回队列头部的元素,如果队列为空,则抛出异常。

4. poll(:移除并返回队列头部的元素,如果队列为空,则返回null。

5. element(:返回队列头部的元素,但不移除该元素,如果队列为空,则抛出异常。

6. peek(:返回队列头部的元素,但不移除该元素,如果队列为空,则返回null。

以上方法的时间复杂度为O(1)。

除了上述基本操作,Queue接口还有其他一些方法:1. size(:返回队列中的元素个数。

2. isEmpty(:判断队列是否为空。

3. contains(Object o):判断队列是否包含一些元素。

4. clear(:清空队列中的所有元素。

Queue接口有两个主要的实现类:LinkedList和PriorityQueue。

1. LinkedList实现了Queue接口,因此可以在LinkedList对象上使用Queue的所有方法。

LinkedList内部通过双向链表实现队列,因此可以高效地在两端进行元素的添加和移除。

它是一个非线程安全的实现。

以下是PriorityQueue类中定义的一些方法:1. offer(E e):向队列中插入一个元素,该操作的时间复杂度为O(log(n))。

Java优先级队列实现

public int peek() throws Exception{ if(this.size == 0) throw new Exception("Queue is empty!"); return data[size-1]; }
public int size(){ return this.size; }
public boolean isEmpty(){ return (size == 0); }
public boolean isFull(){ return (size == data.length); } }
由于插入操作有可能需要移动数组中的数据项,故插入操作的时间复杂度为(0+N)/2,即O(N) 删除操作的时间复杂度为O(1)
由于插入操作有可能需要移动数组中的数据项故插入操作的时间复杂度为0n2即on
Java优 先 级 队 列 实 现
优先级队列数组实现:
public class PriorityQueue { private int[] data; private int size;
public PriorityQueue(int size){ data = new int[size]; this.size = 0; }
public void push(int toInsert) throws Exception{ if(size == data.length) throw new Exception("Queue is full!"); if(size == 0){ data[0] = toInsert; }else{ int i = size -1; for( ; i >= 0 ; i--){
if(data[i] < toInsert){ data[i+1] = data[i]; }else{ break; } } data[i+1] = toInsert; } size++; }

queue的用法java

queue的用法java队列(Queue)是一种数据结构,它遵循先进先出(FIFO)的原则,即最早加入队列的元素最早被取出。

在Java中,有多种方式可以实现队列,其中最常见的是使用java.util.Queue接口及其实现类。

一、java.util.Queue接口java.util.Queue是java.util包中的一个接口,它定义了队列的通用行为。

Java提供了多个Queue实现类,如LinkedList、ArrayDeque等。

使用这些类创建队列非常简单,只需创建一个对象即可。

二、使用LinkedList实现QueueLinkedList类实现了Queue接口,因此可以使用它来创建队列。

以下是一个使用LinkedList实现Queue的示例:```javaQueue<String>queue=newLinkedList<>();queue.add("apple");//添加元素到队列中queue.add("banana");//添加元素到队列中StringfrontElement=queue.poll();//从队列中取出第一个元素System.out.println(frontElement);//输出:apple```三、使用ArrayDeque实现QueueArrayDeque类也实现了Queue接口,但它与LinkedList相比,更适合于频繁的入队和出队操作。

以下是一个使用ArrayDeque实现Queue的示例:```javaQueue<String>queue=newArrayDeque<>();queue.add("apple");//添加元素到队列中queue.add("banana");//添加元素到队列中StringfrontElement=queue.pollFirst();//从队列中取出第一个元素(等同于poll()方法)System.out.println(frontElement);//输出:apple```四、其他Queue实现类除了LinkedList和ArrayDeque之外,Java还提供了其他一些Queue实现类,如PriorityQueue等。

java~优先级队列PriorityQueue

java~优先级队列PriorityQueue概念PriorityQueue是⼀种⽀持排序的优先级队列,你⼊队列的对象需要实现Comparable或Comparator接⼝,或者它本⾝⽀持⾃然排序,如Integer,Long这些类型(这些类型也都实现了Comparable接⼝)。

数据结构优先级队列底层的数据结构其实是⼀颗⼆叉堆,什么是⼆叉堆呢?我们来看看下⾯的图(a为⼤顶堆,b为⼩顶堆)在这⾥我们会发现以下特征:⼆叉堆是⼀个完全⼆叉树根节点总是⼤于左右⼦节点(⼤顶堆),或者是⼩于左右⼦节点(⼩顶堆)。

java代码例⼦定义⼀个对象,实现Comparable接⼝@Datastatic class Customer implements Comparable<Customer> {private int id;private String name;public Customer(int i, String n) {this.id = i; = n;}public int getId() {return id;}public String getName() {return name;}@Overridepublic int compareTo(Customer o) {if (this.id < o.id) return -1; // ⼩于⽬标值,返回-1表⽰升序,即-1表⽰数值由⼩到⼤的排序else if (this.id == o.id) return 0;else return 1;}}添加测试⽤例@Testpublic void test() {Queue<Customer> priorityQueue = new PriorityQueue<>();priorityQueue.add(new Customer(1, "zhansan"));priorityQueue.add(new Customer(2, "lisi"));priorityQueue.add(new Customer(4, "wangwu"));while (!priorityQueue.isEmpty()) {Customer cust = priorityQueue.poll();System.out.println("Processing Customer =" + cust.toString());}}测试结果,按着id的升序出队列Processing Customer =PriorityQueueTest.Customer(id=1, name=zhansan)Processing Customer =PriorityQueueTest.Customer(id=2, name=lisi)Processing Customer =PriorityQueueTest.Customer(id=4, name=wangwu)。

Java中的集合(四)PriorityQueue常用方法

Java中的集合(四)PriorityQueue常⽤⽅法Java中的集合(四)PriorityQueue常⽤⽅法PriorityQueue的基本概念等都在上⼀篇已说明,感兴趣的可以点击 查看这⾥主要以PriorityQueue的常⽤⽅法的学习⼀、PriorityQueue的实现

从上图中给层序遍历编号,从中可以发现⽗⼦节点总有如下的关系:通过上述三个公式,可以轻易计算出某个节点的⽗节点以及⼦节点的下标。这也就是为什么可以直接⽤数组来存储堆的原因。PriorityQueue的peek()和element()操作是常数时间,add()、offer()、 ⽆参数的remove()以及poll()⽅法的时间复杂度都是log(N)。

⼆、PriorityQueue常⽤的⽅法 三、常⽤⽅法剖析(⼀)插⼊元素:add(E e)和offer(E e)add(E e)和offer(E e)两者的语义是相同,都是往优先队列中插⼊元素,只是Queue接⼝规定了两者对插⼊失败时采取不同的处理⽅式。add(E e)⽅法插⼊元素失败时会抛出异常,offer(E e)插⼊元素失败时会返回false,对PriorityQueue⽽⾔,两者没有什么区别。

1 public boolean add(E e) { 2 return offer(e); // add⽅法内部调⽤offer⽅法 3 } 4 public boolean offer(E e) { 5 if (e == null) // 元素为空的话,抛出NullPointerException异常 6 throw new NullPointerException(); 7 modCount++; 8 int i = size; 9 if (i >= queue.length) // 如果当前⽤堆表⽰的数组已经满了,调⽤grow⽅法扩容10 grow(i + 1); // 扩容11 size = i + 1; // 元素个数+112 if (i == 0) // 堆还没有元素的情况13 queue[0] = e; // 直接给堆顶赋值元素14 else // 堆中已有元素的情况15 siftUp(i, e); // 重新调整堆,从下往上调整,因为新增元素是加到最后⼀个叶⼦节点16 return true;17 }18 private void siftUp(int k, E x) {19 if (comparator != null) // ⽐较器存在的情况下20 siftUpUsingComparator(k, x); // 使⽤⽐较器调整21 else // ⽐较器不存在的情况下22 siftUpComparable(k, x); // 使⽤元素⾃⾝的⽐较器调整23 }24 private void siftUpUsingComparator(int k, E x) {25 while (k > 0) { // ⼀直循环直到⽗节点还存在26 int parent = (k - 1) >>> 1; // 找到⽗节点索引,等同于(k - 1)/ 227 Object e = queue[parent]; // 获得⽗节点元素28 // 新元素与⽗元素进⾏⽐较,如果满⾜⽐较器结果,直接跳出,否则进⾏调整29 if (comparator.compare(x, (E) e) >= 0) 30 break;31 queue[k] = e; // 进⾏调整,新位置的元素变成了⽗元素32 k = parent; // 新位置索引变成⽗元素索引,进⾏递归操作33 }34 queue[k] = x; // 新添加的元素添加到堆中35 }

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

在Java 中,优先队列是一种基于堆的数据结构,通常用于实现具有优先级的队列。

在优先队列中,元素按照它们的优先级被处理,而不是按照它们被插入的顺序。

Java 中的PriorityQueue 类是一个标准的优先队列实现,它可以存储可比较的元素,并根据它们的比较顺序进行排列。

以下是Java 中PriorityQueue 的基本用法:
导入PriorityQueue 类:
import java.util.PriorityQueue;
创建一个优先队列:
PriorityQueue<T> priorityQueue = new PriorityQueue<>();
其中,T 是要存储在队列中的元素类型。

默认情况下,它会根据元素的自然顺序进行排序。

如果要使用自定义的比较规则,可以提供一个Comparator 对象作为参数。

添加元素到优先队列:
priorityQueue.add(element); // 或priorityQueue.offer(element);
这将把元素插入到优先队列中,并根据优先级对其进行排序。

获取队列中的最高优先级元素(头元素):
T highestPriorityElement = priorityQueue.peek();
如果队列为空,peek 方法将返回null。

移除并返回队列中的最高优先级元素(头元素):
T highestPriorityElement = priorityQueue.poll();
如果队列为空,poll 方法将返回null。

检查队列是否为空:
boolean isEmpty = priorityQueue.isEmpty();
获取队列中的元素数量:
int size = priorityQueue.size();
使用自定义比较器:
如果要使用自定义的比较器,可以在创建优先队列时传递一个Comparator 对象,或者使用具有自定义比较器的构造函数:
PriorityQueue<T> customPriorityQueue = new PriorityQueue<>(customComparator);
自定义比较器的示例:
Comparator<Integer> customComparator = new Comparator<Integer>() { @Override
public int compare(Integer num1, Integer num2) {
// 返回正数表示num1 的优先级高,返回负数表示num2 的优先级高
return num1 - num2;
}
};
优先队列在许多算法和数据结构中都有广泛应用,例如最小堆、Dijkstra算法、Prim算法等。

它允许你高效地管理具有不同优先级的元素,以便在需要时能够快速找到和处理最高优先级的元素。

相关文档
最新文档