- 大顶堆:当前节点值大于其左右节点,可用来计算top K小的元素
- 小顶堆:当前节点值小于其左右节点,可用来计算top K大的元素
#include <bits/stdc++.h> using namespace std; /* 堆排序算法实现: 大顶堆的建立,以及堆的维护 当前节点大于其左右节点,每次筛选出最大的节点,可以维持最小的K个元素 算法时间复杂度,O(nlogn) */ void HeapAdjust(int a[], int len, int index){ //对a[index]--a[len]元素进行排序,使得a[index]为最大元素 int left = 2 * index; int right = 2 * index + 1; int max_index = index; if(left <= len && a[left] > a[max_index]) max_index = left; if(right <= len && a[right] > a[max_index]) max_index = right; if(max_index != index){//最大元素所在位置有更新 swap(a[max_index], a[index]); //元素交换位置 HeapAdjust(a, len, max_index); } } void HeapSort(int a[], int len){ for(int i = len/2; i > 0; i--) HeapAdjust(a, len, i);//对每一个非叶子节点从后往前进行调整,生成初始大顶堆 for(int i = len -1; i >= 1; i--){ swap(a[i+1], a[1]); //将当前最大元素放到数组末尾 HeapAdjust(a, i, 1); //对未完成部分继续进行堆排序 } } int main(){ int a[9] = {0, 49, 97, 65, 49, 76, 13, 27, 38}; HeapSort(a, 8); for(int i = 1; i <= 8; i++) cout<<a[i]<<endl; }
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
#include "bits/stdc++.h"
using namespace std;
class Solution {
private:
int val;
public:
int Partition(vector<int>& nums, int l, int h){
//对nums[l...h]元素进行筛选,将nums[l]放置到合适的位置
int temp = nums[l];
int low = l, high = h;
while(low < high){
while(low < high && nums[high] > temp){
//从右一直往左扫描,直到不满足条件
high -= 1;
}
swap(nums[low], nums[high]);
while(low < high && nums[low] <= temp){
//从左一直往右扫描,直到不满足条件
low += 1;
}
swap(nums[low], nums[high]);
}
nums[low] = temp;
return low;
}
void quick_sort(vector<int> nums, int l, int h, int k){
if(l <= h){
int p = Partition(nums, l, h);
if(p == k){
val = nums[p];
return;
}else if(p < k){
quick_sort(nums, p+1, h, k);
}else if(p > k){
quick_sort(nums, l, p-1, k);
}
}else{
return;
}
}
int findKthLargest(vector<int>& nums, int k) {
//使用快排,快排返回位置刚好为k,返回即可
int l = 0, h = nums.size()-1;
int index = nums.size() - k;
quick_sort(nums, l, h, index);
return val;
}
int findKthLargest_heap(vector<int>& nums, int k) {
//使用小顶堆(大小为k)
vector<int>::const_iterator first1 = nums.begin();
vector<int>::const_iterator last1 = nums.begin() + k;
vector<int> vec(first1, last1);
for(int i = (k-1) / 2; i >= 0; i--){
Heapadjust(vec, k, i);
}
for(int i = k; i < nums.size(); i++){
if(nums[i] > vec[0])//大于堆顶元素,替换即可
{
vec[0] = nums[i];
Heapadjust(vec, k, 0);
}
}
return vec[0];
}
void Heapadjust(vector<int>& nums, int len, int index){
//对下标为index的元素进行调整
int left_index = 2 * index, right_index = 2 * index + 1;
int min_index = index;
if(left_index < len && nums[left_index] <= nums[min_index]){
min_index = left_index;
}
if(right_index < len && nums[right_index] <= nums[min_index]){
min_index = right_index;
}
if(min_index != index){
swap(nums[index], nums[min_index]);
Heapadjust(nums, len, min_index);
}
}
};