【Java数据结构】集合PriorityQueue及其背后的数据结构堆(优先级队列)(二)

简介: 【Java数据结构】集合PriorityQueue及其背后的数据结构堆(优先级队列)

堆的删除

注意:堆的删除一定删除的是堆顶元素。具体如下:

1. 将堆顶元素对堆中最后一个元素交换

2. 将堆中有效数据个数减少一个

3. 对堆顶元素进行向下调整

1. public void pollHeap() {
2. if(isEmpty()){
3. throw new RuntimeException();
4.         }
5. int temp=elem[0];
6.         elem[0]=elem[usedSize-1];
7.         elem[usedSize-1]=temp;
8.         usedSize--;
9. //保证依然是大根堆
10.         shiftDown(0,usedSize);
11. 
12.     }
13. 
14. public boolean isEmpty() {
15. return usedSize==0;
16.     }
17. 
18. /**
19.      *
20.      * @param root 是每棵子树的根节点的下标
21.      * @param len  是每棵子树调整结束的结束条件
22.      * 向下调整的时间复杂度:O(logn)
23.      */
24. private void shiftDown(int root,int len) {
25. 
26. int child=2*root+1;
27. 
28. while(child<len){
29. 
30. if(child+1<len&&elem[child]<elem[child+1]){
31. 
32.                 child++;
33.             }
34. 
35. if(elem[root]<elem[child]){
36. int temp=elem[root];
37.                 elem[root]=elem[child];
38.                 elem[child]=temp;
39.                 root=child;
40.                 child=2*root+1;
41. 
42.             }else {
43. break;
44.             }
45. 
46.         }
47. 
48. 
49.     }

用堆模拟实现优先级队列(完整代码)

1. import java.util.Arrays;
2. 
3. public class PriorityQueue {
4. public int[] elem;
5. public int usedSize;
6. 
7. public static final int DEFAULT_INIT_USESZIE=10;
8. public PriorityQueue() {
9.         elem=new int[DEFAULT_INIT_USESZIE];
10.     }
11. 
12. /**
13.      * 建堆的时间复杂度:O(n)
14.      *
15.      * @param array
16.      */
17. public void createHeap(int[] array) {
18. 
19. 
20. 
21. for(int i=0;i<array.length;i++){
22.             elem[i]=array[i];
23.             usedSize++;
24. if(isFull()){
25.                 elem= Arrays.copyOf(this.elem,2*this.elem.length);
26.             }
27.         }
28. for(int parent=(usedSize-1-1)/2;parent>=0;parent--){
29. 
30.             shiftDown(parent,usedSize);
31.         }
32. 
33.     }
34. 
35. /**
36.      *
37.      * @param root 是每棵子树的根节点的下标
38.      * @param len  是每棵子树调整结束的结束条件
39.      * 向下调整的时间复杂度:O(logn)
40.      */
41. private void shiftDown(int root,int len) {
42. 
43. int child=2*root+1;
44. 
45. while(child<len){
46. 
47. if(child+1<len&&elem[child]<elem[child+1]){
48. 
49.                 child++;
50.             }
51. 
52. if(elem[root]<elem[child]){
53. int temp=elem[root];
54.                 elem[root]=elem[child];
55.                 elem[child]=temp;
56.                 root=child;
57.                 child=2*root+1;
58. 
59.             }else {
60. break;
61.             }
62. 
63.         }
64. 
65. 
66.     }
67. 
68. 
69. /**
70.      * 入队:仍然要保持是大根堆
71.      * @param val
72.      */
73. public void push(int val) {
74. if(isFull()){
75.             elem= Arrays.copyOf(this.elem,2*this.elem.length);
76.         }
77.         elem[usedSize]=val;
78.         usedSize++;
79.         shiftUp(usedSize-1);
80. 
81.     }
82. 
83. private void shiftUp(int child) {
84. 
85. int parent=(child-1)/2;
86. 
87. while(child>0)
88. if(elem[child]>elem[parent]){
89. 
90. int temp=elem[child];
91.             elem[child]=elem[parent];
92.             elem[parent]=temp;
93.             child=parent;
94.             parent=(child-1)/2;
95.         }else{
96. break;
97.         }
98.     }
99. 
100. public boolean isFull() {
101. return usedSize== elem.length;
102.     }
103. 
104. /**
105.      * 出队【删除】:每次删除的都是优先级高的元素
106.      * 仍然要保持是大根堆
107.      */
108. public void pollHeap() {
109. if(isEmpty()){
110. throw new RuntimeException();
111.         }
112. int temp=elem[0];
113.         elem[0]=elem[usedSize-1];
114.         elem[usedSize-1]=temp;
115.         usedSize--;
116. //保证依然是大根堆
117.         shiftDown(0,usedSize);
118. 
119.     }
120. 
121. public boolean isEmpty() {
122. return usedSize==0;
123.     }
124. 
125. /**
126.      * 获取堆顶元素
127.      * @return
128.      */
129. public int peekHeap() {
130. if(isEmpty()){
131. return -1;
132.         }
133. return elem[0];
134.     }
135. }

常用接口介绍

Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,本文主要介绍PriorityQueue。

关于PriorityQueue的使用要注意:

1. 使用时必须导入PriorityQueue所在的包,即:

import java.util.PriorityQueue;

2. PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出

ClassCastException异常

3. 不能插入null对象,否则会抛出NullPointerException

4. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容

5. 插入和删除元素的时间复杂度为

6. PriorityQueue底层使用了堆数据结构, (注意:此处大家可以不用管什么是堆,后文中有介绍)

7. PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素

PriorityQueue常用接口介绍

构造器 功能介绍
PriorityQueue() 创建一个空的优先级队列,默认容量是11
PriorityQueue(int
initialCapacity)
创建一个初始容量为initialCapacity的优先级队列,注意:
initialCapacity不能小于1,否则会抛IllegalArgumentException异
PriorityQueue(Collection<?
extends E> c)
用一个集合来创建优先级队列

注意:默认情况下,PriorityQueue队列是小堆,如果需要大堆需要用户提供比较器

1. // 用户自己定义的比较器:直接实现Comparator接口,然后重写该接口中的compare方法即可
2. class IntCmp implements Comparator<Integer>{
3. @Override
4. public int compare(Integer o1, Integer o2) {
5. return o2-o1;
6. }
7. }
8. public class TestPriorityQueue {
9. public static void main(String[] args) {
10. PriorityQueue<Integer> p = new PriorityQueue<>(new IntCmp());

插入/删除/获取优先级最高的元素

函数名 功能介绍
boolean
offer(E e)
插入元素e,插入成功返回true,如果e对象为空,抛出NullPointerException异常,时
间复杂度 ,注意:空间不够时候会进行扩容
E peek() 获取优先级最高的元素,如果优先级队列为空,返回null
E poll() 移除优先级最高的元素并返回,如果优先级队列为空,返回null
int size() 获取有效元素的个数
void
clear()
清空
boolean
isEmpty()
检测优先级队列是否为空,空返回true
相关文章
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
210 9
|
25天前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
49 5
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
1月前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
1月前
|
存储 Java 调度
Java 中的优先队列 PriorityQueue 详解
【10月更文挑战第22天】优先队列 PriorityQueue 是一种非常实用的数据结构,在许多场景中都能发挥重要作用。通过深入了解其特点和用法,我们可以更好地利用它来解决实际问题。
111 13
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
2月前
初步认识栈和队列
初步认识栈和队列
65 10
|
2月前
|
存储 算法 Java
🏗️Java零基础:深入了解Java 堆
【10月更文挑战第2天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
29 3
|
2月前
【数据结构】-- 栈和队列
【数据结构】-- 栈和队列
21 0
|
2月前
探索数据结构:队列的的实现与应用
探索数据结构:队列的的实现与应用

热门文章

最新文章