返回
堆:数据结构中的顺序存储树
后端
2023-10-28 15:10:56
在数据结构(四):二叉树中,我们探索了使用链式结构实现树。在本篇中,我们将介绍堆,一种使用顺序结构实现的特殊树形数据结构。
为什么要用顺序存储?
堆是一种完全二叉树,这意味着每个节点都有 0 个或 2 个子节点。这种结构允许我们使用数组进行顺序存储,从而避免了链式结构中指针带来的开销和内存碎片。
堆的特性
堆具有以下特性:
- 完全二叉树: 所有级别(除了最底层)都完全填充。
- 堆序: 对于任意节点,其子节点的值都小于(或大于)其自身的值,形成最大堆(或最小堆)。
堆的操作
堆支持以下操作:
- 插入: 将新元素插入堆并维护堆序。
- 删除: 从堆中删除根元素并维护堆序。
- 查找: 找到堆中最大(或最小)的元素。
堆的应用
堆在计算机科学中广泛应用于:
- 优先级队列: 用于存储具有不同优先级的元素。
- 排序算法: 堆排序是一种使用堆进行排序的有效算法。
- 数据结构: 堆可以作为其他数据结构(如优先级队列和散列表)的基础。
代码示例
以下是一个在 C++ 中实现最大堆的代码示例:
#include <vector>
class MaxHeap {
private:
std::vector<int> heap;
public:
// 插入
void insert(int value) {
heap.push_back(value);
heapifyUp(heap.size() - 1);
}
// 删除
int removeMax() {
int max = heap[0];
heap[0] = heap[heap.size() - 1];
heap.pop_back();
heapifyDown(0);
return max;
}
// 查找最大值
int getMax() {
return heap[0];
}
private:
// 从下往上维护堆序
void heapifyUp(int index) {
while (index > 0) {
int parent = (index - 1) / 2;
if (heap[index] > heap[parent]) {
swap(heap[index], heap[parent]);
index = parent;
} else {
break;
}
}
}
// 从上往下维护堆序
void heapifyDown(int index) {
while (index < heap.size()) {
int left = 2 * index + 1;
int right = 2 * index + 2;
int largest = index;
if (left < heap.size() && heap[left] > heap[largest]) {
largest = left;
}
if (right < heap.size() && heap[right] > heap[largest]) {
largest = right;
}
if (largest != index) {
swap(heap[index], heap[largest]);
index = largest;
} else {
break;
}
}
}
};
总结
堆是一种使用顺序存储实现的完全二叉树,具有堆序特性。它支持高效的插入、删除和查找操作,在计算机科学中广泛应用于优先级队列、排序算法和数据结构。