数据结构_堆
Created: 2023-11-28T16:46+08:00
堆
- 定义
- 堆是一棵完全二叉树
- 每个父节点大于子节点就是大顶堆,反之就是小顶堆
- 优先队列可以用堆实现
- 建堆:自底向上
- 新增元素:上浮
- 弹出元素:下沉
- 例题
- topK
堆的建立
Binary Heap - Insert, Sift Up, Delete, Sift Down, Heapify(BuildHeap) - YouTube
堆的建立使用的是 sift down + bottom top 的方法,从最后一个非叶子节点开始 sift down,逐步调整到 root。
每一次对非叶子节点 sift down,就会导致该节点开始以下的部分变成一个堆。
复杂度是
在我看来,堆的建立使用了分治法中“合并”的思想:给定两个堆和一个数,合并成一个新的堆。
给定一个数组,那么堆的建立就是自底向上的,整个大堆任意取一个点,该点以下部分构成一个「子堆」,两个子堆加上一个 root,对 root sift down 就完成新堆的构建。
可以利用 Java 中的 ArrayList 结构实现堆
import java.util.ArrayList; public class test { public static void main(String[] args) { ArrayList<Integer> nums = new ArrayList<>(); for (int i = 0; i < 10; i++) { nums.add(i); } printOnedArray(nums); for (int i = nums.size() / 2; i >= 0; i--) { keepHeapAttrib(nums, i); } printOnedArray(nums); } // 保证堆的性质 public static void keepHeapAttrib(ArrayList<Integer> heap, int index) { int left = 2 * index + 1; int right = 2 * index + 2; int max = index; if (left < heap.size() && heap.get(left) > heap.get(max)) max = left; if (right < heap.size() && heap.get(right) > heap.get(max)) max = right; if (max != index) { int temp = heap.get(index); heap.set(index, heap.get(max)); heap.set(max, temp); keepHeapAttrib(heap, max); // 递归解决 } } public static void printOnedArray(ArrayList<Integer> array) { for (int i = 0; i < array.size(); i++) { System.out.print(array.get(i) + " "); } System.out.println(); } }
add 和 delete
对于大根堆来说,新增元素,就是在堆最后新增一个叶子,然后一直上浮,直到该新增的数为根节点或比父节点小
对于大根堆来说,弹出元素,就是删除根节点,然后把最后一个叶子取出来,做一次 sift down 就变成了堆的构建算法。
例题
如果您有任何关于文章的建议,欢迎评论或在 GitHub 提 PR
作者:dutrmp19
本文为作者原创,转载请在 文章开头 注明出处:https://www.cnblogs.com/dutrmp19/p/15918316.html
遵循 CC 4.0 BY-SA 版权协议
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本