当前位置: 首页 > article >正文

数据结构与算法-05堆优先队列-02

堆的时间复杂度

如下图所示,调整元素72到达堆顶(最大堆),一共进行了2次交换。

image-20241210191704228

从层的角度分析

堆的高度为h,进行上浮(floatUp) 和下沉(swimDown)操作最大时间与层级(高度h)有关,时间复杂度O(h)。

从节点数量分析

堆是一颗完全二叉树,完全二叉树的时间复杂度与节点有关: O(log2n),此处n为二叉树的节点数量。

image-20241210192352093


Heapify(堆化)

什么是heapify

Heapify is the process of creating a heap data structure from a binary tree. It is used to create a Min-Heap or a Max-Heap. Heapify是将heap调整为最大堆或最小堆的过程,我们以最大堆为例,演示调整过程。

image-20240903095500788

heapify的实现过程

找到最后一个非叶子节点

在二叉堆的数组表示中,如果堆的大小(即数组中元素的数量)为size,那么最后一个非叶子节点的索引就是size / 2 - 1。因为从size / 2开始,数组中的元素都是叶子节点,它们没有子节点,所以不需要进行heapify操作

image-20241210195324370

image-20241210195503395

找到左子节点,右子节点

image-20241210195533798

image-20241210195636519

假设插入heapify中的是父节点,算出其左、右子节点索引

//记录当前节点为最高值节点
int highIndex = currIndex;
int leftIndex = 2 * currIndex + 1;
int rightIndex = 2 * currIndex + 2;

更新左、右子节点的最大值

//更新左、右节点的最大值
if (leftIndex < size && data[leftIndex] > data[hightIndex]) highIndex = leftIndex;
if (rightIndex < size && data[rightIndex] > data[highIndex]) highIndex = rightIndex;

交换当前值与左右子节点最大值

//交换最大值索引
if (highIndex != currIndex) {
    T tmp = data[highIndex];
    data[highIndex] = data[currIndex];
    data[currIndex] = tmp;
    heapify(highIndex);
}

传入数组通过heapify进行调整为堆

public MyHeap(Integer[] data) {
    this.data = data;
    this.size = data.length;
    //在二叉堆的数组表示中,如果堆的大小(即数组中元素的数量)为size,
    // 那么最后一个非叶子节点的索引就是size / 2 - 1。因为从size / 2开始,
    // 数组中的元素都是叶子节点,它们没有子节点,所以不需要进行heapify操作
    for (int i = size / 2 - 1; i >= 0; i--) {
        heapify(i);
    }
}

heapify的时间复杂度

如果使用offer()添加

一个数据进行堆化时间复杂度为logn, 如果多个数据按照这样添加时间复杂度: nlogn

快速堆化过程

image-20240903141042275

  1. 计算heapify的平均时间复杂度

    时间复杂度 = 求和(每层节点数 * 移动数)

    image-20240903142843093

    image-20240903150430425

    image-20240903150403821

    image-20240903150450711 image-20240903151437304

Heapify的时间复杂度: O(n)

替换堆顶(replace)

替换堆顶元素,将堆顶替换,swim堆。

public void replace(T newVal) {
    if (isEmpty()) {
        return;
    }
    data[0] = newVal;
    swim(0);
}

优先队列(PriorityQueue)

Java PriorityQueue类是一种队列数据结构实现,其中根据优先级处理对象。它与遵循FIFO(先进先出)算法的标准队列不同。

在优先级队列中,添加的对象根据其优先级。默认情况下,优先级由对象的自然顺序决定。队列构建时提供的比较器可以覆盖默认优先级。

image-20240901110339842

PriorityQueue特性

java 的PriorityQueue是最小堆

List<Integer> list = new ArrayList<>();
list.add(56);
list.add(25);
list.add(30);
list.add(70);

PriorityQueue<Integer> queue
        = new PriorityQueue<>();
queue.addAll(list);
System.out.println(queue);

运行结果

[25, 56, 30, 70]

修改为最大堆

List<Integer> list = new ArrayList<>();
list.add(56);
list.add(25);
list.add(30);
list.add(70);

PriorityQueue<Integer> queue
        = new PriorityQueue<>(Comparator.reverseOrder());
queue.addAll(list);
System.out.println(queue);

运行结果

[70, 56, 30, 25]

api

offer()

image-20240901112305122

remove()/poll()

image-20240901112421549

peek()

image-20240901112558897


http://www.kler.cn/a/444621.html

相关文章:

  • netcore 集成Prometheus
  • 数据结构漫游记:初识vector
  • 进程与线程以及如何查看
  • 15.初识接口1 C#
  • clickhouse-题库
  • 揭秘区块链隐私黑科技:零知识证明如何改变未来
  • [Unity]Unity跨平台开发之Android简介
  • webpack常用配置讲解
  • 零基础学安全--wireshark简介
  • 健身达人微信小程序的设计与实现ssm+论文源码调试讲解
  • 视频监控/远程视频监控汇聚系统Liveweb网络监控解决方案
  • 【前端】CSS
  • excel 使用vlook up找出两列中不同的内容
  • Qt WORD/PDF(一)使用 QtPdfium库实现 PDF 预览
  • electron窗口锁定、解锁、解决阴影问题
  • 37. Three.js案例-绘制部分球体
  • 科技查新报告需要多长时间能完成?
  • 第10章:CSS最佳实践 --[CSS零基础入门]
  • 构建一个rust生产应用读书笔记四(实战5)
  • 大模型和呼叫中心的结合如何提高自动化水平?
  • L2tp环境搭建笔记- Openwrt平台
  • Redis bitmaps 使用
  • 国标GB28181网页直播平台EasyGBS:网络摄像机中的音频及音频编码技术解析
  • day14-16系统服务管理和ntp和防火墙
  • 【Rust自学】4.1. 所有权:栈内存 vs. 堆内存
  • Unity中实现通过控制Scroll View内物体顺序来做排序