数据结构——堆
堆(Heap)是一种常见的数据结构,用于维护一组元素,并支持高效地找到最大值或最小值。在堆中,每个节点的值都必须满足特定的堆性质,即父节点的值要么大于等于(最大堆)或小于等于(最小堆)其子节点的值。
堆通常用于优先队列、排序算法等场景,其中最常见的是二叉堆(Binary Heap)。二叉堆是一种完全二叉树(Complete Binary Tree),它可以使用数组实现,并且满足堆性质。
以下是一个用 C++ 实现的最小堆的示例:
#include <iostream>
#include <vector>
class MinHeap {
private:
std::vector<int> heap;
// 获取节点的父节点索引
int parent(int index) {
return (index - 1) / 2;
}
// 获取节点的左子节点索引
int leftChild(int index) {
return 2 * index + 1;
}
// 获取节点的右子节点索引
int rightChild(int index) {
return 2 * index + 2;
}
// 交换数组中两个元素的值
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
// 向上调整节点,使其满足堆性质
void heapifyUp(int index) {
while (index > 0 && heap[parent(index)] > heap[index]) {
swap(heap[index], heap[parent(index)]);
index = parent(index);
}
}
// 向下调整节点,使其满足堆性质
void heapifyDown(int index) {
int smallest = index;
int left = leftChild(index);
int right = rightChild(index);
if (left < heap.size() && heap[left] < heap[smallest]) {
smallest = left;
}
if (right < heap.size() && heap[right] < heap[smallest]) {
smallest = right;
}
if (smallest != index) {
swap(heap[index], heap[smallest]);
heapifyDown(smallest);
}
}
public:
// 插入元素到堆中
void insert(int value) {
heap.push_back(value);
int index = heap.size() - 1;
heapifyUp(index);
}
// 获取堆中的最小值
int getMin() {
if (heap.empty()) {
throw std::out_of_range("Heap is empty.");
}
return heap[0];
}
// 删除堆中的最小值
void deleteMin() {
if (heap.empty()) {
throw std::out_of_range("Heap is empty.");
}
heap[0] = heap.back();
heap.pop_back();
heapifyDown(0);
}
};
int main() {
MinHeap minHeap;
// 插入元素到堆中
minHeap.insert(4);
minHeap.insert(2);
minHeap.insert(6);
minHeap.insert(1);
minHeap.insert(5);
// 获取并删除堆中的最小值
int minVal = minHeap.getMin();
std::cout << "最小值:" << minVal << std::endl;
minHeap.deleteMin();
// 获取并删除堆中的最小值
minVal = minHeap.getMin();
std::cout << "最小值:" << minVal << std::endl;
minHeap.deleteMin();
return 0;
}
上述示例中,定义了一个最小堆的类 MinHeap,它使用 std::vector 实现底层的数组。该类提供了插入元素、获取最小值和删除最小值的操作。插入操作将新元素添加到堆的末尾,并通过向上调整节点来维护堆性质。获取最小值操作直接返回堆顶元素的值。删除最小值操作将堆顶元素与末尾元素交换,并通过向下调整节点来维护堆性质。
在 main 函数中,首先创建了一个最小堆对象 minHeap,然后通过调用 insert 操作将元素 4、2、6、1 和 5 插入堆中。接着,分别调用 getMin 和 deleteMin 操作获取并删除堆中的最小值。最后,输出结果。输出结果为:
最小值:1
最小值:2
这个示例展示了最小堆的基本操作,包括插入元素、获取最小值和删除最小值。最小堆常用于需要高效地获取最小值的场景,如优先队列、图算法(如 Dijkstra 算法)等。