PHP堆实现TopK算法实例,top-k 算法浅析
簡介
top-k算法,其實(shí)就是尋找最大的k個數(shù)(具體詳見《編程之美》第2.5節(jié)“尋找最大的k個數(shù)”)。比如一個數(shù)組:1,2,5,9,4,3,7 需要尋找最大的2個數(shù),那么就是9和7。最早之前我接觸到topk算法的時候,覺得解決思路就是排序,排完序之后,取前k個數(shù)就可以了。但是這種思路雖然簡單,但是效率是很差的。因?yàn)轭}目只要求最大的k個數(shù),并不需要k個數(shù)有序,也不需要后n-k個數(shù)有序。
解決方法
我用的是解法四,用一個容量為k的最小堆來儲存最大的k個數(shù)。最小堆的堆頂元素就是最大k個數(shù)中最小的一個。每次新考慮一個數(shù)x,如果x比堆頂?shù)脑貀小,則不需要改變原來的堆,因?yàn)檫@個元素比最大的k個數(shù)小。如果x比堆頂?shù)脑卮?#xff0c;那么用x替換堆頂?shù)脑貀。在x替換堆頂元素y后,x可能破壞最小堆的結(jié)構(gòu)(每個結(jié)點(diǎn)都比它的父親結(jié)點(diǎn)大),需要更新堆來維持堆的性質(zhì)。
代碼實(shí)現(xiàn)(C語言)
#include
#include
// 定義取最大N個數(shù)
#define TOP_K 6
int heap[6];
// 交換數(shù)據(jù)
void swap(int *a, int *b)
{
int temp = *b;
*b = *a;
*a = temp;
}
// 調(diào)整最小堆
void min_heapify(int arr[], int start, int end)
{
int dad = start;
int son = dad * 2 + 1;
while (son <= end)
{
if (son + 1 <= end && arr[son] > arr[son + 1])
son++;
if (arr[dad] < arr[son])
return;
else
{
swap(&arr[dad], &arr[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
// 建立最小堆
void buid_heap(int heap[])
{
int i;
for (i = TOP_K / 2; i >= 0; i--)
{
min_heapify(heap, i, TOP_K - 1);
}
}
// 8,8,8,9,9,9
int main()
{
int arr[] = {3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6};
int len = (int)sizeof(arr) / sizeof(*arr);
int i;
// 堆賦值
for (i = 0; i < TOP_K; i++)
{
heap[i] = arr[i];
}
buid_heap(heap); // 建立最小堆
// 循環(huán)遍歷整個數(shù)組
for (i = TOP_K + 1; i <= len; i++)
{
if (arr[i] > heap[0]) // 只有大于根節(jié)點(diǎn)才處理
{
heap[0] = arr[i];
min_heapify(heap, 0, TOP_K - 1); // 向下調(diào)整堆
}
}
// 打印最大key個數(shù)
for (i = 0; i < TOP_K; i++)
{
printf("%d ", heap[i]);
}
}
總結(jié)
以上是生活随笔為你收集整理的PHP堆实现TopK算法实例,top-k 算法浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: h5列表 php,常用的HTML5列表标
- 下一篇: php mssql 新 id,MSSQL