#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class MaxHeap {
private:
vector<int> data;
// 当一个元素被添加到堆的末尾时,此方法用来保持堆的属性。
// 它从给定的索引处开始,不断与其父节点比较,如果当前节点大于其父节点,则它们两者的位置互换。
// 这个过程一直重复,直到当前节点小于等于其父节点或者已经到达堆的顶部。
void heapifyUp(int index) {
while (index > 0) {
int parent = (index - 1) / 2;
if (data[index] <= data[parent]) {
break;
}
swap(data[index], data[parent]);
index = parent;
}
}
// 当堆顶元素被移除后,通常将最后一个元素移到顶部,然后使用此方法向下调整以保持堆的属性。
// 它将当前节点与其子节点比较,并与更大的一个子节点交换位置。
// 这个过程一直进行到没有更大的子节点或已经到达堆的底部。
void heapifyDown(int index) {
int n = data.size();
while (true) {
int largest = index;
int left = 2 * index + 1;
int right = 2 * index + 2;
if (left < n && data[left] > data[largest]) {
largest = left;
}
if (right < n && data[right] > data[largest]) {
largest = right;
}
if (largest == index) {
break;
}
swap(data[index], data[largest]);
index = largest;
}
}
public:
MaxHeap() {}
// 向堆中插入一个新的元素。首先将新元素添加到向量的末尾,然后调用 heapifyUp 方法以保持大根堆的属性。
void insert(int value) {
data.push_back(value);
heapifyUp(data.size() - 1);
}
// 移除并返回堆中的最大元素(堆顶元素)。此方法首先保存顶部元素的值,然后将向量的最后一个元素移至顶部,并移除原本的最后一个元素。之后调用 heapifyDown 方法从新的顶部开始重新整理堆。
int extractMax() {
if (data.empty()) {
throw runtime_error("Heap is empty");
}
int max = data[0];
data[0] = data.back();
data.pop_back();
heapifyDown(0);
return max;
}
// 返回堆顶元素的值,即最大值。如果堆为空,则抛出异常。
int getMax() const {
if (data.empty()) {
throw runtime_error("Heap is empty");
}
return data[0];
}
bool isEmpty() const { return data.empty(); }
};
// 具体使用返回数组中的第k个最大的值
int findKthLargest(vector<int>& nums, int k) {
MaxHeap* mh = new MaxHeap();
for (auto n : nums) {
mh->insert(n);
}
int res;
for (int i = 0; i < k; i++) {
res = mh->extractMax();
}
return res;
}