堆在存储器中的表示是数组,堆只是一个概念上的表示。堆的同一节点的左右子节点都没有规律。

堆适合优先级队列(默认排列顺序是升序排列,快速插入与删除最大/最小值)。

数组与堆

堆(完全二叉树)(构造大顶堆或者小顶堆的时间复杂度:O(logn))

堆实现的优先级队列虽然和数组实现相比删除慢了些,但插入的时间快的多了:
当速度很重要且有很多插入操作时,可以选择堆来实现优先级队列。
堆插入删除的效率:时间复杂度是:O(logn)。 小顶堆:父节点的值 <= 左右孩子节点的值
大顶堆:父节点的值 >= 左右孩子节点的值 堆的定义:n个关键字序列array[0,...,n-1]: 若array[0,...,n-1]表示一颗完全二叉树的顺序存储模式,则双亲节点指针和孩子结点指针之间的内在关系如下: 任意一节点指针 i(0 <= i <= (n-1)/2) : 父节点:i==0 ? null : (i-1)/2 左孩子:2*i + 1 右孩子:2*i + 2 ① array[i] <= array[2*i + 1] 且 array[i] <= array[2*i + 2] : 称为小根堆 ② array[i] >= array[2*i + 1] 且 array[i] >= array[2*i + 2] : 称为大根堆 堆的插入( add(e),offer(e) ):添加到末尾,由于可能破坏堆结构,需要调整(向上筛选) 插入使用向上筛选,向上筛选的算法比向下筛选的算法相对简单,因为它不需要比较两个子节点关键字值的大小 删除操作 ( remove(o) ):由于可能破坏堆结构,需要调整(向下筛选) 删除堆顶 ( poll() ):由于可能破坏堆结构,需要调整(向下筛选) 移除是指删掉关键字值最大的节点,即根节点。   在被筛选节点的每个暂时停留的位置,向下筛选的算法总是要检查哪一个子节点更大,然后目标节点和较大的子节点交换位置

堆排序(时间复杂度:O(nlogn))

堆排序是一种树形选择排序方法,它的特点是:
在排序的过程中,将array[0,...,n-1]看成是一颗完全二叉树的顺序存储结构,
利用完全二叉树中双亲节点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(最小)的元素。 步骤:
构造堆
固定最大值再构造堆(将最大值元素(堆头)与堆尾元素交换,将其他数再构造成最大堆)
重复上述过程 堆(二叉堆)排序的时间复杂度,最好,最差,平均都是O(nlogn),空间复杂度O(1),是不稳定的排序。

PriorityQueue

public class PriorityQueue<E> extends AbstractQueue<E>
implements java.io.Serializable { private static final long serialVersionUID = -7720805057305804111L; private static final int DEFAULT_INITIAL_CAPACITY = 11; transient Object[] queue; // non-private to simplify nested class access int size; private final Comparator<? super E> comparator; transient int modCount; // non-private to simplify nested class access public PriorityQueue(Collection<? extends E> c) {} //使用已有集合构建二叉堆 public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
} public PriorityQueue(int initialCapacity,
Comparator<? super E> comparator) { if (initialCapacity < 1)
throw new IllegalArgumentException();
this.queue = new Object[initialCapacity];
this.comparator = comparator;
}
} //自定义比较器,降序排列
static Comparator<Integer> cmp = new Comparator<Integer>() {
public int compare(Integer e1, Integer e2) {
return e2 - e1;
}
};

在未排序的数组中找到第 k 个最大的元素

/**
* 示例 1:
* 输入: [3,2,1,5,5,4] 和 k = 2
* 输出: 5
*
* 时间复杂度 : O(Nlogk)。
* 空间复杂度 : O(k),用于存储堆元素。
*/ /**
* 小顶堆
*/
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int i = 0; i < nums.length; i++) {
pq.add(nums[i]);
if(pq.size()>k)pq.poll();
}
return pq.poll();
}
}

找出动态有序列表的中位数

/**
* 中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
*
* 例如,
* [2,3,4] 的中位数是 3
* [2,3] 的中位数是 (2 + 3) / 2 = 2.5
*
* 方法:最大堆与最小堆。
* 思路:各存储一半,最大堆的堆顶比最小堆的堆顶小。
*
* 时间复杂度:O(logN),从堆里得到一个 “最值” 而其它元素无需排序
* 空间复杂度:O(N)
*/
class MedianFinder1 {
/**
* 当前大顶堆和小顶堆的元素个数之和
*/
private int count;
private PriorityQueue<Integer> maxheap;
private PriorityQueue<Integer> minheap; /**
* initialize your data structure here.
*/
public MedianFinder1() {
count = 0;
maxheap = new PriorityQueue<>((x, y) -> y - x); //大顶堆
minheap = new PriorityQueue<>(); //小顶堆
} public void addNum(int num) {
count += 1;
maxheap.offer(num);
minheap.add(maxheap.poll());
// 如果两个堆合起来的元素个数是奇数,小顶堆要拿出堆顶元素给大顶堆
if ((count & 1) != 0) {
maxheap.add(minheap.poll());
}
} public double findMedian() {
if ((count & 1) == 0) {
// 如果两个堆合起来的元素个数是偶数,数据流的中位数就是各自堆顶元素的平均值
return (double) (maxheap.peek() + minheap.peek()) / 2;
} else {
// 如果两个堆合起来的元素个数是奇数,数据流的中位数大顶堆的堆顶元素
return (double) maxheap.peek();
}
}
}

最强堆排序文章

https://blog.csdn.net/u010452388/article/details/81283998

二叉堆 与 PriorityQueue的更多相关文章

  1. D&F学数据结构系列——二叉堆

    二叉堆(binary heap) 二叉堆数据结构是一种数组对象,它可以被视为一棵完全二叉树.同二叉查找树一样,堆也有两个性质,即结构性和堆序性.对于数组中任意位置i上的元素,其左儿子在位置2i上,右儿 ...

  2. python下实现二叉堆以及堆排序

    python下实现二叉堆以及堆排序 堆是一种特殊的树形结构, 堆中的数据存储满足一定的堆序.堆排序是一种选择排序, 其算法复杂度, 时间复杂度相对于其他的排序算法都有很大的优势. 堆分为大头堆和小头堆 ...

  3. 优先队列之二叉堆与d-堆

    二叉堆简介 平时所说的堆,若没加任何修饰,一般就是指二叉堆.同二叉树一样,堆也有两个性质,即结构性和堆序性.正如AVL树一样,对堆的以此操作可能破坏者两个性质中的一个,因此,堆的操作必须要到堆的所有性 ...

  4. 《数据结构与算法分析:C语言描述》复习——第五章“堆”——二叉堆

    2014.06.15 22:14 简介: 堆是一种非常实用的数据结构,其中以二叉堆最为常用.二叉堆可以看作一棵完全二叉树,每个节点的键值都大于(小于)其子节点,但左右孩子之间不需要有序.我们关心的通常 ...

  5. 二叉堆(binary heap)—— 优先队列的实现

    二叉堆因为对应着一棵完全二叉树,因而可以通过线性数组的方式实现. 注意,数组第 0 个位置上的元素,作为根,还是第 1 个位置上的元素作为根? 本文给出的实现,以数组第 1 个位置上的元素作为根,则其 ...

  6. 纯数据结构Java实现(6/11)(二叉堆&优先队列)

    堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). ...

  7. 【nodejs原理&源码杂记(8)】Timer模块与基于二叉堆的定时器

    [摘要] timers模块部分源码和定时器原理 示例代码托管在:http://www.github.com/dashnowords/blogs 一.概述 Timer模块相关的逻辑较为复杂,不仅包含Ja ...

  8. 【nodejs原理&源码杂记(8)】Timer模块与基于二叉堆的定时器

    目录 一.概述 二. 数据结构 2.1 链表 2.2 二叉堆 三. 从setTimeout理解Timer模块源码 3.1 timers.js中的定义 3.2 Timeout类定义 3.3 active ...

  9. 二叉堆的BuildHeap操作

    优先队列(二叉堆)BuildHeap操作 \(BuildHeap(H)\)操作把\(N\)个关键字作为输入并把它们放入空堆中.显然,这可以使用\(N\)个相继的\(Insert\)操作来完成.由于每个 ...

随机推荐

  1. Spring、SpringMVC、SpringBoot、SpringCloud概述

    spring和springMvc: 1. spring是一个一站式的轻量级的java开发框架,核心是控制反转(IOC)和面向切面(AOP),针对于开发的WEB层(springMvc).业务层(Ioc) ...

  2. 浅谈CICD持续集成、持续部署的流程(转)

    Jenkins是一个比较流行的持续集成工具GitLab是存储镜像的镜像仓库由客户端将代码push推送到git仓库,gitlab上配置了一个webHook的东西可以触发Jenkins的构建.进入到Jen ...

  3. JavaSE---基本数据类型存储大小

  4. String path = request.getContextPath();报错

    String path = request.getContextPath();报错 1. 右击该项目 - Build Path - Configure Build Path , 在 Libraries ...

  5. Linq 使用Startswith 出现空引用的问题

    一.问题 我使用的是Entity Fromwork CodeFirst来操作数据库,昨天在使用startswith查询数据的时候发现一个问题,就是经常一直报空引用的错误,查了很久才找到原因,这里做一个 ...

  6. C# GDI+简单绘图

    一.使用Pen画笔 Pen的主要属性有: Color(颜色),DashCap(短划线终点形状),DashStyle(虚线样式),EndCap(线尾形状), StartCap(线头形状),Width(粗 ...

  7. CDN技术之--流媒体CDN系统的组成

    流媒体业务是一种对实时性.连续性.时序性要求非常高的业务,无论从带宽消耗上还是质量保障上来说,对best-effort的IP网络都是一个不小的冲击 –高带宽要求–高QoS要求–组播.广播要求(目前IP ...

  8. Xcode5 统计单元测试覆盖率(仅限XCTest)

    概要 通过本篇文章,你将学会如何在Xcode5下使用统计XCTest测试代码的覆盖率,以及如何快速得到测试覆盖率的图形化报表. 为什么要特别说明Xcode5下的代码覆盖率统计,原因是,以前的方法在新环 ...

  9. 前端每日实战:80# 视频演示如何用纯 CSS 创作一个自行车车轮

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/XBXEPK 可交互视频 此视频是可 ...

  10. Angularjs可以查看scope的插件AngularJS Batarang

    AngularJS Batarang是一个显示AngularJS的scope 层次的Chrome插件,有效的快速查看一个page 中有多少Scope能够帮助我们快速方便调试AngularJS程序. 插 ...