最大堆、最小堆数据结构详细解读
创作时间:
作者:
@小白创作中心
最大堆、最小堆数据结构详细解读
引用
CSDN
1.
https://blog.csdn.net/m0_61840987/article/details/143624484
堆是一种重要的数据结构,广泛应用于优先队列、排序算法、调度系统等场景。本文将详细介绍最大堆和最小堆的定义、特性、核心操作及其应用场景。
最大堆(Max Heap)与最小堆(Min Heap)
堆(Heap)是一种特殊的完全二叉树,它满足以下两个特性:
- 结构特性:堆必须是完全二叉树(Complete Binary Tree)。即除了最后一层之外,其他层都必须完全填满,且最后一层的节点从左向右连续排列。
- 堆特性:
- 最大堆(Max Heap):每个节点的值都大于或等于其子节点的值。
- 最小堆(Min Heap):每个节点的值都小于或等于其子节点的值。
堆广泛用于优先队列、排序算法(如堆排序)、调度系统等场景。下面是对最大堆和最小堆的详细介绍。
一、最大堆(Max Heap)
- 定义
- 最大堆是一种完全二叉树,满足堆特性:每个节点的值都大于或等于其子节点的值。
- 因此,堆顶元素(根节点)是整个堆中的最大值。
- 结构示意图
- 根节点 50 是堆中的最大值。
- 对于任意节点,其值都大于或等于其子节点的值。
- 核心操作
插入(Insert):
- 将新元素插入堆的最后一个位置。
- 通过上浮(Percolate Up)调整堆的顺序,直到满足堆特性。
删除最大元素(Extract Max):
- 取出堆顶元素(最大值)。
- 将堆的最后一个元素移动到堆顶。
- 通过下沉(Percolate Down)调整堆的顺序,直到满足堆特性。
- 代码实现(Java 示例)
import java.util.Arrays;
class MaxHeap {
private int[] heap;
private int size;
private int capacity;
public MaxHeap(int capacity) {
this.capacity = capacity;
heap = new int[capacity];
size = 0;
}
// 获取父节点索引
private int parent(int index) {
return (index - 1) / 2;
}
// 获取左子节点索引
private int leftChild(int index) {
return 2 * index + 1;
}
// 获取右子节点索引
private int rightChild(int index) {
return 2 * index + 2;
}
// 上浮操作
private void percolateUp(int index) {
while (index > 0 && heap[parent(index)] < heap[index]) {
swap(index, parent(index));
index = parent(index);
}
}
// 下沉操作
private void percolateDown(int index) {
int largest = index;
int left = leftChild(index);
int right = rightChild(index);
if (left < size && heap[left] > heap[largest]) {
largest = left;
}
if (right < size && heap[right] > heap[largest]) {
largest = right;
}
if (largest != index) {
swap(index, largest);
percolateDown(largest);
}
}
// 插入元素
public void insert(int value) {
if (size == capacity) throw new RuntimeException("Heap is full");
heap[size] = value;
size++;
percolateUp(size - 1);
}
// 删除最大元素
public int extractMax() {
if (size == 0) throw new RuntimeException("Heap is empty");
int max = heap[0];
heap[0] = heap[size - 1];
size--;
percolateDown(0);
return max;
}
// 交换元素
private void swap(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
// 打印堆
public void printHeap() {
System.out.println(Arrays.toString(Arrays.copyOfRange(heap, 0, size)));
}
}
public class MaxHeapTest {
public static void main(String[] args) {
MaxHeap maxHeap = new MaxHeap(10);
maxHeap.insert(50);
maxHeap.insert(30);
maxHeap.insert(20);
maxHeap.insert(15);
maxHeap.insert(10);
maxHeap.insert(5);
maxHeap.insert(8);
maxHeap.printHeap(); // 输出: [50, 30, 20, 15, 10, 5, 8]
System.out.println("Extract Max: " + maxHeap.extractMax()); // 输出: 50
maxHeap.printHeap(); // 输出: [30, 15, 20, 8, 10, 5]
}
}
- 时间复杂度
- 插入操作:O(logn)
- 删除最大元素:O(logn)
- 查找最大元素:O(1)
二、最小堆(Min Heap)
- 定义
- 最小堆是一种完全二叉树,满足堆特性:每个节点的值都小于或等于其子节点的值。
- 因此,堆顶元素(根节点)是整个堆中的最小值。
- 结构示意图
- 根节点 5 是堆中的最小值。
- 对于任意节点,其值都小于或等于其子节点的值。
- 核心操作
插入(Insert):
- 将新元素插入堆的最后一个位置。
- 通过上浮(Percolate Up)调整堆的顺序,直到满足堆特性。
删除最小元素(Extract Min):
- 取出堆顶元素(最小值)。
- 将堆的最后一个元素移动到堆顶。
- 通过下沉(Percolate Down)调整堆的顺序,直到满足堆特性。
- 代码实现(Java 示例)
class MinHeap {
private int[] heap;
private int size;
private int capacity;
public MinHeap(int capacity) {
this.capacity = capacity;
heap = new int[capacity];
size = 0;
}
private int parent(int index) {
return (index - 1) / 2;
}
private int leftChild(int index) {
return 2 * index + 1;
}
private int rightChild(int index) {
return 2 * index + 2;
}
private void percolateUp(int index) {
while (index > 0 && heap[parent(index)] > heap[index]) {
swap(index, parent(index));
index = parent(index);
}
}
private void percolateDown(int index) {
int smallest = index;
int left = leftChild(index);
int right = rightChild(index);
if (left < size && heap[left] < heap[smallest]) {
smallest = left;
}
if (right < size && heap[right] < heap[smallest]) {
smallest = right;
}
if (smallest != index) {
swap(index, smallest);
percolateDown(smallest);
}
}
public void insert(int value) {
if (size == capacity) throw new RuntimeException("Heap is full");
heap[size] = value;
size++;
percolateUp(size - 1);
}
public int extractMin() {
if (size == 0) throw new RuntimeException("Heap is empty");
int min = heap[0];
heap[0] = heap[size - 1];
size--;
percolateDown(0);
return min;
}
private void swap(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
}
- 时间复杂度
- 插入操作:O(logn)
- 删除最小元素:O(logn)
- 查找最小元素:O(1)
三、最大堆与最小堆的应用
数据结构 | 应用场景 |
|---|---|
最大堆 | 优先队列(最大优先级)、实时数据流中的第 K 大元素 |
最小堆 | 优先队列(最小优先级)、Dijkstra 最短路径算法 |
堆的特性使其在许多场景下非常有用,如调度系统、事件模拟、动态中位数维护等。
热门推荐
红玫瑰葡萄种植技术和管理
集训赋能,锻造过硬“兵教头”!
十首宴饮古诗词,开琼筵以坐花,飞羽觞而醉月
心率窦性心律不齐:原因、症状与应对方法
如何在云平台修改数据库
对事故责任认定书不服怎么办?详解复核申请流程与注意事项
多人使用不当受伤!管道疏通剂千万别这么用
甲状腺结节的“深度体检”:超声引导下甲状腺结节细针穿刺活检术
荷叶茶减肥效果如何?科学解读其减肥原理与饮用方法
心理科普 | 双相情感障碍的常见征兆和临床3大类型
八字命理学中有哪些主要流派
求新谋变 中国车企加速“出海”圈粉
连续骗保近两百次、非法获利上百万元,“碰瓷王”落网!
ERP系统中的欺诈行为及应对策略
左肺纤维灶:成因、表现及处理方法
如何与孩子沟通才能保持良好的亲子关系
人如何提升认知(思想力):规律、规则、人心与道、法、术
教育市场创新趋势报告:成人和职业教育寻路新就业周期
200种花卉花语全集:从常见到冷门,每朵花都有它的故事
宝宝上户籍贯规定可随父随母,如何确定有两大方法
浅析美国空军新装备的SiAW导弹
“弹簧刀”巡飞弹的制导关键技术
干货!大模型的训练过程详解
非洲草原上的长颈鹿种群动态观察
燃气热水器工作原理,一次给你讲明白!
小区公共收益全解析:来源、管理、使用及查询方法
小区里的公共收益由谁管理,小区公共收益如何管理?
4K 120Hz与2K 360Hz电竞显示器对比:分辨率与刷新率的终极对决
医疗产品外观设计:如何实现简洁与大气
中央台风网助力抗风减灾,提升中国台风预警能力