面试常见题之TopK问题

一:堆的一个应用就是优先级队列:
优先级队列(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[N] = {0};
    int heap[K] = {0};

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

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

时间复杂度为O(N*logK)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值