详解优先级队列(堆)

本文详细介绍了堆的概念,包括大根堆和小根堆的定义,以及堆的创建和初始化。接着讲解了堆的方法构建,如入队列、出队列和查看头元素的操作。此外,还探讨了优先级队列的使用,包括堆排序的实现和寻找最小K对数字的解决方案,分别利用小堆和大堆进行实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、堆的概念以及堆的创建

1、堆的概念

2、堆的创建

二、堆的方法的构建

2.1 入队列操作

2.2出队列操作

2.3查看头元素

三、优先级队列(堆)方法的使用

3.1堆的初始化(大堆和小堆的创建)

四、堆排序(大堆)

五、查找和最小的K对数字

5.1利用小堆来实现

5.2利用大堆来实现


一、堆的概念以及堆的创建

1、堆的概念

什么是堆?(堆的逻辑上是一个完全二叉树,实际上是保存在数组中)

我们把一个完全二叉树通过层序遍历存储到数组当中,这个数组就叫做堆。

 注意:堆中的元素不能为空。(浪费大量空间)

 什么是大根堆和小根堆?

大根堆:所有结点的值都大于其子结点的值,我们称为大根堆。

小根堆:所有结点的值都小于其子结点的值,我们称为小根堆。

 

 注意:父亲结点为i时,左孩子的结点为i*2+1,右孩子的结点为i*2+2;

            孩子结点为i时,父亲结点为(i-1)/2;

2、堆的创建

 2.1向下遍历

对于堆中的排序我们可以采用向下遍历的方法,我们就拿小堆的向下遍历来做例子。

 2.2建堆操作

由于堆的底层是数组,我们开始要创建一个数组并且初始化。

public class TestHeap {
    public int[] elem;
    public int uesdSize;

    public TestHeap(){
        this.elem=new int[10];
    }
}

接下来我们要将一段无序的数组放进去,并且通过elem数组拷贝进来,同时我们通过由下向上不断遍历由上向下的函数。

    public void createBigHeap(int[] array){
        for(int i=0;i<array.length;i++){
            this.elem[i]=array[i];
            this.usedSize++;
        }

        for(int i=(this.usedSize-1-1)/2;i>=0;i--){
            shiftDown(i);
        }
    }

接下来我们编写由上向下的函数shiftDown(i);

    public void shiftDown(int parent){
        int child=parent*2+1;
        while (child<this.usedSize){
            if(child+1<this.usedSize && this.elem[child+1]<this.elem[child]){
                child++;
            }

            if(this.elem[parent]>this.elem[child]){
                int temp=this.elem[parent];
                this.elem[child]=this.elem[parent];
                this.elem[parent]=temp;

                parent=child;
                child=child*2+1;
            }else {
                break;
            }
        }
    }

注意:一般来说for循环的时间复杂度为N,shiftDown的时间复杂度为logN,所以为O(N*logN),但是实际上为O(N);

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

now just do it

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值