您的位置:首页 > 职场人生

面试常见题之TopK问题

2017-03-30 08:38 381 查看
一:堆的一个应用就是优先级队列:
优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有(1)查找(2)插入一个新元素 (3)删除 一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 。对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。
如:

template<class T,class Compare =Greater<T>>
class PriorityQueue
{
public:
void Push(const T&x)
{
_hp.Push(x);
}
void Pop()
{
_hp.Pop();
}
size_t Size()
{
return _hp.Size();
}
bool Empty()
{
return _hp.Empty();
}
const T&Top()
{
return _hp.Top();
}

protected:
Heap<T, Compare>_hp;
};
void TestPriorityQueue()
{
int a[] = { 14, 10, 56, 7, 83, 22, 36, 91, 3, 47 };
PriorityQueue<int, Greater<int>> hp;
for (size_t i = 0; i < 10; i++)
{
hp.Push(a[i]);
}
while (!hp.Empty())
{
cout << hp.Top() << " ";
hp.Pop();
}
cout << endl;
}

二:Topk问题:
问题描叙:在N(N>>10000)个数据中找到最大的K个数
分析;这时海量数据的问题,只要前K个,输出整个数据的保存和排序都是不可取的,我们可以建一个小堆用来保存这k个数据,然后再那N-K个数据与小堆的最小值比较,大的数据进堆,直到N-K数据比较完为止

#pragma once
#include<iostream>
#include<queue>
#include<assert.h>
using namespace std;
#define N 1000
#define K 10
template<class T>
void AdjustDown(T*heap,size_t root)
{
size_t parent = root;
size_t child = parent * 2 + 1;
while (child< K)
{
//找最小的孩子
if (child + 1 < K&& heap[child+1] < heap[child])
{
child++;
}
if (child <K&&heap[child] < heap[parent])
{
swap(heap[child], heap[parent]);
parent = child;
child = parent * 2 +1;
}
else
{
break;
}
}
}
//堆里面存放k个数据
template<class T>
void Topk( T*a, T*heap)
{
assert(N > K);
for (size_t i = 0; i < K;++i)
{
heap[i] = a[i];
}
//调整成小堆
for (int j = (K - 2) / 2; j >= 0; --j)
{
AdjustDown(heap,j);
}
//如果数组里面的数据比堆里面的最小值大则入堆;
for (size_t i = K; i < N; ++i)
{

if (a[i]>heap[0])
{
swap(a[i], heap[0]);
AdjustDown(heap,0);
}
}
}
template<class T>
void Print(T *heap)
{
int k = 10;
for (size_t i = 0; i < K; i++)
{
cout << heap[i] << " ";

}
cout << endl;
}
void TestTopK()
{

int a
= {0};
int heap[K] = {0};

for (int i = 0; i < N; ++i)
{
a[i] = i;
}

Topk(a,heap);
Print(heap);
}




时间复杂度为O(N*logK)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: