小根堆 总结

小根堆


如果有一个关键字的集合K={k0,k1,k2, ..., kn-1}, 把所有元素按完全二叉树的顺序存储
方式存放在一个一维数组中,并且满足
ki <= k2i+1 且 ki <= k2i+2  (i = 0, 1, ..., (n-2)/2 向上取整)
则称这个集合为小根堆。

小根堆的创建:
1. 复制堆数组
2. 找到最初的调整位置,即最后一个分支结点
3.1自底向上逐步扩大形成堆
3.2 向前换一个分支结点

小根堆的插入:
1. 将待插入元素插入已建成堆的最后面
2. 沿着出入位置所在的分支逐步向上调整

小根堆的删除:
1. 将顶元素删除

2. 将数组中最后一个元素放到堆顶

3. 自顶向下调整







### 小根堆作为优先队列的实现与应用 #### 1. 小根堆的基本概念 小根堆是一种特殊的完全二叉树结构,其中任意父节点的关键字值小于等于其左右孩子节点的关键字值。这种特性使得堆顶始终存储的是整个堆中的最小值[^1]。 #### 2. 使用小根堆实现优先队列 优先队列是一种抽象数据类型,支持动态集合操作,包括插入新元素和删除具有最高优先权的元素。当使用小根堆实现优先队列时,堆顶总是代表当前队列中优先级最低(即数值最小)的元素[^4]。 以下是基于小根堆实现优先队列的核心功能: ##### (1)构建小根堆 为了初始化一个由数组表示的小根堆,需从最后一个非叶子节点开始向上执行“下沉”操作(sift down),从而确保整棵树满足小根堆性质。 ```java public void createHeap(int[] array) { int root = (array.length - 2) / 2; for (; root >= 0; root--) { siftDown(array, root); } } private void siftDown(int[] heap, int index) { int n = heap.length; while ((index * 2 + 1) < n) { // 存在左子节点 int childIndex = index * 2 + 1; if (childIndex + 1 < n && heap[childIndex + 1] < heap[childIndex]) { childIndex++; // 右子节点更小时选择右子节点 } if (heap[index] <= heap[childIndex]) break; // 已经满足小根堆条件 swap(heap, index, childIndex); // 否则交换父子节点 index = childIndex; } } private void swap(int[] array, int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } ``` ##### (2)插入元素 向小根堆中插入新元素时,首先将其添加到堆底,随后通过上浮操作(sift up)恢复堆序性。 ```java public void insert(int value) { size++; data[size - 1] = value; siftUp(size - 1); } private void siftUp(int index) { while (index > 0) { int parentIndex = (index - 1) / 2; if (data[parentIndex] <= data[index]) break; // 满足小根堆条件 swap(data, parentIndex, index); index = parentIndex; } } ``` ##### (3)提取最小值 从小根堆中移除并返回堆顶元素的操作涉及两步:一是替换堆顶为最后一位元素;二是重新调整堆使其保持小根堆属性。 ```java public int extractMin() throws Exception { if (size == 0) throw new Exception("Heap is empty"); int min = data[0]; data[0] = data[--size]; // 替换堆顶为最后一位元素 siftDown(data, 0); // 调整堆 return min; } ``` #### 3. 小根堆的应用场景 小根堆广泛应用于各种算法问题中,尤其是那些需要频繁访问或更新最小值的情况。例如,在处理数据流中寻找前 K 大元素的任务时,可以利用小根堆维护这 K 个最大的数[^2]。 另一个典型应用场景是在多链表排序问题中。假设存在若干已排序单链表,目标是以 O(n log k) 的时间复杂度合并它们成一个新的有序列表,则可以通过建立容量为 k 的小根堆来高效完成此任务[^3]。 #### 总结 综上所述,小根堆作为一种高效的优先队列实现方式,凭借其独特的结构性质提供了快速存取极值的能力,并适用于多种实际编程挑战之中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值