转载于:https://zhuanlan.zhihu.com/p/37350934
这两种方式都是使用堆的思路来做的,所以时间复杂度相比于其他的实现快一点。
1、第一种代码 ,默认是浮点型的topk,如果需要切换成整形数组topk,应注意把代码所有地方的float 类型改成 float
由于c语言对类型转换非常敏感,整形转浮点型可能会导致精度损失,比如float类型的 0.3333 直接赋值int类型,就会直接置为0。务必注意!
/*
寻找n个不同数据中第k大的元素
接口:int top_k(int *a,int n,int k);
输入:一个由n个不同元素组成的数组a,a的长度n以及k的值
输出:数组a中第k大的元素
*/
#include<stdio.h>
#define max_size 10001
float min_heap[max_size]={0.0}; //假定数组中的数都是正数
int heap_count=0;
void reheap(int k) //更新根节点的数值后,调整使其符合最小堆
{
int root=0;
int child=root*2+1;
while(child<k)
{
if((child+1)<k&&min_heap[child+1]<min_heap[child])
child++;
if(min_heap[root]<min_heap[child])
return;
float temp=min_heap[root];
min_heap[root]=min_heap[child];
min_heap[child]=temp;
root=child;
child=root*2+1;
}
}
float top_k(float *a,int n,int k)
{
int i;
for(int i=0;i<n;i++)
if(a[i]>min_heap[0])
{
min_heap[0]=a[i];
reheap(k);
}
return min_heap[0];
}
int main(void)
{
float array[10]={1.2,4.5,2.4,5.6,7.6,7.8,5.8,7.8,9.1,3.8};
float x=top_k(array,9,5);
printf("%.1f\n",x);
return 0;
}
第二种实现方式:
提供第k大的数和第k小的数,两种方案;默认求解的是第k大的数
#include<stdio.h>
//topk 第k大的数
void maxHeapify(float* a, int i, int heapSize)
{
int l = i * 2 + 1, r = i * 2 + 2, largest = i;
if (l < heapSize && a[l] > a[largest])
{
largest = l;
}
if (r < heapSize && a[r] > a[largest])
{
largest = r;
}
if (largest != i)
{
float t = a[i];
a[i] = a[largest], a[largest] = t;
maxHeapify(a, largest, heapSize);
}
}
//topk 第k小的数
void minHeapify(float* a, int i, int heapSize)
{
int l = i * 2 + 1, r = i * 2 + 2, largest = i;
if (l < heapSize && a[l] < a[largest])
{
largest = l;
}
if (r < heapSize && a[r] < a[largest])
{
largest = r;
}
if (largest != i)
{
float t = a[i];
a[i] = a[largest], a[largest] = t;
minHeapify(a, largest, heapSize);
}
}
void buildMinHeap(float* a, int heapSize)
{
for (int i = heapSize / 2; i >= 0; --i)
{
maxHeapify(a, i, heapSize);
}
}
float findKthLargest(float* nums, int numsSize, int k)
{
int heapSize = numsSize;
buildMinHeap(nums, heapSize);
for (int i = numsSize - 1; i >= numsSize - k + 1; --i)
{
float t = nums[0];
nums[0] = nums[i], nums[i] = t;
--heapSize;
maxHeapify(nums, 0, heapSize);
}
return nums[0];
}
int main(void)
{
float array[10]={0.14,0.12,0.13,0.11,0.18,0.11,0.17,0.19,0.16,0.15};
printf("%f\n",findKthLargest(array,10,5));
return 0;
}