堆(Heap)与优先队列

本文介绍了堆的基本概念,包括大顶堆和小顶堆的性质,并详细阐述了堆的插入和删除操作。堆常用于实现优先队列,如Java中的PriorityQueue类。文章通过LeetCode题目,展示了如何利用堆解决数据流中的第K大元素、数组中的第K个最大元素等实际问题,强调了堆在维护集合最值方面的应用。
摘要由CSDN通过智能技术生成

堆(Heap)与优先队列

堆的基础知识

堆是一个完全二叉树,可以采用数组形式存储

下标从0开始,i位置的节点:

左孩子坐标为:2 * i + 1;

右孩子坐标为:2 * i + 2;

父亲节点坐标为:(i - 1) / 2;

Java中的PriorityQueue类(优先队列)是堆的实现类

大顶堆:

性质:

在二叉树任意的三元子中,根节点都大于两个子节点的堆

最大值在堆顶,第二大的值在根节点的左节点或右节点中。

兄弟之间无大小关系

堆适合维护:集合最值

小顶堆:

性质:

在二叉树任意的三元子中,根节点都小于两个子节点的堆

最小值在堆顶,第二小的值在根节点的左节点或右节点中。

兄弟之间无大小关系

堆—尾部插入调整(插入元素)

将新节点不断地与其父节点比较,新节点大于父节点则与父节点交换位置。

堆—头部弹出调整(删除元素)

大顶堆:弹出的是堆中的最大值

小顶堆:弹出的是堆中的最小值

在弹出堆顶元素之后,数组长度应该减一。原0下标的元素因为被弹出,所以为空,那么我们就把原数组中末尾的元素**(为了方便将其记为a)插入到下标0的位置上去。随后我们要进行堆性质的维护,每一次都从三元组中选择一个最大的节点与a交换,直到元素a**是三元组中最大的节点。

堆排序

—待完善

堆–优先队列的一种实现方式

普通队列 (最大/最小)堆
尾部入队 尾部可以插入
头部出队 头部可以弹出
先进先出 每次出队权值(最大/最小的元素)
数组实现 数组实现,逻辑上看成一个堆

堆的代码实现

大顶堆:

import java.util.Arrays;
class BigHeap{
   
    int size;
    int[] bigHeap;
    public BigHeap() {
   
        this.size = 0;
        this.bigHeap = new int[10];//默认是10大小
    }
    public BigHeap(int n) {
   
        this.size = 0;
        this.bigHeap = new int[n];
    }
    //返回堆大小的方法
    public int size(){
   
        return size;
    }
    //返回堆顶元素的方法
    public int top(){
   
        return bigHeap[0];
    }
    //向堆中插入元素的方法
    public void push(int num){
   
        if(size == bigHeap.length) return;//数组满了无法插入
        bigHeap[size] = num;
        int index = size++;//堆中元素数量加一,index为最后一个元素的下标
        while(index > 0 && bigHeap[(index - 1) / 2] < num){
   //保证下标不越界并且可以比较大小
            swap(bigHeap,index,(index - 1) / 2);
            index = (index - 1) / 2;
        }
    }
    //删除堆顶元素的方法
    public int pop(){
   
        if(size == 0)
            return 0;
        int num = bigHeap[0];
        bigHeap[0] = bigHeap[size - 1];
        bigHeap[size - 1] = 0;//这里不写也是可以的,写了主要是为了toString观看方便,因为插入新值的时候会把老值覆盖掉
        size -= 1;
        int n = size - 1;//n为数组中最后一个元素的下标
        int index = 0;//这是要向下进行置换的元素
        while((index * 2 + 1) <= n){
   //判断是否越界
            int temp = index;
            if(bigHeap[temp] < bigHeap[index * 2 + 1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值