堆的特性:是一个完全二叉树,假设下标从零开始,对于索引cur而言:
- 左孩子:2*cur+1;
- 右孩子:2*cur+2;
- 父节点:(cur-1)/2
void maxHeapDown(vector<int> &nums, int start, int end) {
int left = start * 2 + 1;
int right = start * 2 + 2;
int largeIndex;
while (left <= end) {
if (right <= end && nums[left] < nums[right]) {
largeIndex = right;
}
else {
largeIndex = left;
}
if (nums[start] > nums[largeIndex]) {
largeIndex = start;
}
if (largeIndex == start) {
break;
}
swap(nums[start], nums[largeIndex]);
start = largeIndex;
left = 2 * start + 1;
right = 2 * start + 2;
}
}
void maxHeapDown2(vector<int> &nums, int start, int end) {
int c = start;
int l = 2 * c + 1;
int tmp = nums[c];
for (; l <= end; c = l, l = 2 * c + 1) {
if (l < end&&nums[l] < nums[l + 1]) {
l++;
}
if (tmp >= nums[l]) {
break;
}
else {
nums[c] = nums[l];
nums[l] = tmp;
}
}
}
void buildMaxHeap(vector<int> &nums) {
for (int i = nums.size() / 2 - 1; i >= 0; i--) { //倒数第二层从右往左第一个子树
maxHeapDown(nums, i, nums.size() - 1); //从低向上
}
}
void MaxHeapSortAsc(vector<int> &nums) {
buildMaxHeap(nums);
for (int i = nums.size() - 1; i >= 0; i--) {
swap(nums[i], nums[0]);
maxHeapDown(nums, 0, i - 1);
}
}
int findKthLargest(vector<int>& nums, int k) {
buildMaxHeap(nums);
for (int i = nums.size() - 1; i >= nums.size() - k + 1; i--) {
swap(nums[0], nums[i]);
maxHeapDown(nums, 0, i - 1);
}
return nums[0];
}