1 某个节点和自己的子节点交换的时候,不仅会影响到他的父节点(可能导致这节点和父节点不满足堆的定义),也可能会影响他的子节点(因为发生交换,子节点和【子节点的子节点】也不满足堆的定义),所以这就是为啥要在adjust_heap 递归调用adjust_heap来处理交换后的子节点。 2 重建一个小顶堆的时候,需要从第一个非叶子节点开始往上调整(往下调整,递归会做的啦)。 3 从根节点调整一个已经建好的堆的话,可以让整个堆都调整好。
class Solution {
public:
void adjust_heap(vector<int>& heap_1, int root) {
int k = heap_1.size();
int left = 2 * root + 1 , right = 2 * root + 2, min_index = root;
if (left < k && heap_1[left] < heap_1[min_index]) {
min_index = left;
}
if (right < k && heap_1[right] < heap_1[min_index]) {
min_index = right;
}
if (min_index != root) {
swap(heap_1[root], heap_1[min_index]);
adjust_heap(heap_1, min_index); // 这个是处理啥呢?其实是处理交换之后的子节点
}
return;
}
void build_heap(vector<int>& heap_1) {
int len = heap_1.size();
for(int i = len/2-1;i>=0;i--) {
adjust_heap(heap_1, i);
}
}
int findKthLargest(vector<int>& nums, int k) {
vector<int> heap_1;
for(int i=0;i<k;i++) {
heap_1.emplace_back(nums[i]);
}
build_heap(heap_1);
for(int i=k;i<nums.size();i++) {
if (nums[i]> heap_1[0]) {
heap_1[0] = nums[i];
adjust_heap(heap_1,0); //因为是从根节点往下调整的,这时候不需要调用build_heap 来重建堆,会自然而然的重建堆
}
}
return heap_1[0];
}
};